composite-key.js 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. // TODO: in core-js@4, move /modules/ dependencies to public entries for better optimization by tools like `preset-env`
  2. require('../modules/es.map');
  3. require('../modules/es.weak-map');
  4. var global = require('../internals/global');
  5. var getBuiltIn = require('../internals/get-built-in');
  6. var create = require('../internals/object-create');
  7. var isObject = require('../internals/is-object');
  8. var Object = global.Object;
  9. var TypeError = global.TypeError;
  10. var Map = getBuiltIn('Map');
  11. var WeakMap = getBuiltIn('WeakMap');
  12. var Node = function () {
  13. // keys
  14. this.object = null;
  15. this.symbol = null;
  16. // child nodes
  17. this.primitives = null;
  18. this.objectsByIndex = create(null);
  19. };
  20. Node.prototype.get = function (key, initializer) {
  21. return this[key] || (this[key] = initializer());
  22. };
  23. Node.prototype.next = function (i, it, IS_OBJECT) {
  24. var store = IS_OBJECT
  25. ? this.objectsByIndex[i] || (this.objectsByIndex[i] = new WeakMap())
  26. : this.primitives || (this.primitives = new Map());
  27. var entry = store.get(it);
  28. if (!entry) store.set(it, entry = new Node());
  29. return entry;
  30. };
  31. var root = new Node();
  32. module.exports = function () {
  33. var active = root;
  34. var length = arguments.length;
  35. var i, it;
  36. // for prevent leaking, start from objects
  37. for (i = 0; i < length; i++) {
  38. if (isObject(it = arguments[i])) active = active.next(i, it, true);
  39. }
  40. if (this === Object && active === root) throw TypeError('Composite keys must contain a non-primitive component');
  41. for (i = 0; i < length; i++) {
  42. if (!isObject(it = arguments[i])) active = active.next(i, it, false);
  43. } return active;
  44. };