makeFullOrderComparatorKit = (longLived = false) => {
  let numSeen = 0;
  // When dynamically created with short lifetimes (the default) a WeakMap
  // would perform poorly, and the leak created by a Map only lasts as long
  // as the Map.
  const MapConstructor = longLived ? WeakMap : Map;
  const seen = new MapConstructor();
  const tag = r => {
    if (seen.has(r)) {
      return seen.get(r);
    }
    numSeen += 1;
    seen.set(r, numSeen);
    return numSeen;
  };
  const compareRemotables = (x, y) => compareRank(tag(x), tag(y));
  return makeComparatorKit(compareRemotables);
}
Create a comparator kit in which remotables are fully ordered
by the order in which they are first seen by *this* comparator kit.
BEWARE: This is observable mutable state, so such a comparator kit
should never be shared among subsystems that should not be able
to communicate.

Note that this order does not meet the requirements for store
ordering, since it has no memory of deleted keys.

These full order comparator kit is strictly more precise that the
rank order comparator kits above. As a result, any array which is
sorted by such a full order will pass the isRankSorted test with
a corresponding rank order.

An array which is sorted by a *fresh* full order comparator, i.e.,
one that has not yet seen any remotables, will of course remain
sorted by according to *that* full order comparator. An array *of
scalars* sorted by a fresh full order will remain sorted even
according to a new fresh full order comparator, since it will see
the remotables in the same order again. Unfortunately, this is
not true of arrays of passables in general.

@param {boolean=} longLived
@returns {FullComparatorKit}