index.js 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. export class InternMap extends Map {
  2. constructor(entries, key = keyof) {
  3. super();
  4. Object.defineProperties(this, {_intern: {value: new Map()}, _key: {value: key}});
  5. if (entries != null) for (const [key, value] of entries) this.set(key, value);
  6. }
  7. get(key) {
  8. return super.get(intern_get(this, key));
  9. }
  10. has(key) {
  11. return super.has(intern_get(this, key));
  12. }
  13. set(key, value) {
  14. return super.set(intern_set(this, key), value);
  15. }
  16. delete(key) {
  17. return super.delete(intern_delete(this, key));
  18. }
  19. }
  20. export class InternSet extends Set {
  21. constructor(values, key = keyof) {
  22. super();
  23. Object.defineProperties(this, {_intern: {value: new Map()}, _key: {value: key}});
  24. if (values != null) for (const value of values) this.add(value);
  25. }
  26. has(value) {
  27. return super.has(intern_get(this, value));
  28. }
  29. add(value) {
  30. return super.add(intern_set(this, value));
  31. }
  32. delete(value) {
  33. return super.delete(intern_delete(this, value));
  34. }
  35. }
  36. function intern_get({_intern, _key}, value) {
  37. const key = _key(value);
  38. return _intern.has(key) ? _intern.get(key) : value;
  39. }
  40. function intern_set({_intern, _key}, value) {
  41. const key = _key(value);
  42. if (_intern.has(key)) return _intern.get(key);
  43. _intern.set(key, value);
  44. return value;
  45. }
  46. function intern_delete({_intern, _key}, value) {
  47. const key = _key(value);
  48. if (_intern.has(key)) {
  49. value = _intern.get(key);
  50. _intern.delete(key);
  51. }
  52. return value;
  53. }
  54. function keyof(value) {
  55. return value !== null && typeof value === "object" ? value.valueOf() : value;
  56. }