map.ts 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. /* eslint-disable @typescript-eslint/no-explicit-any */
  2. // We have an ES6 Map available, return the native instance
  3. import { getGlobal } from './utils/global';
  4. /** @public */
  5. let bsonMap: MapConstructor;
  6. const bsonGlobal = getGlobal<{ Map?: MapConstructor }>();
  7. if (bsonGlobal.Map) {
  8. bsonMap = bsonGlobal.Map;
  9. } else {
  10. // We will return a polyfill
  11. bsonMap = class Map {
  12. private _keys: string[];
  13. private _values: Record<string, any>;
  14. constructor(array: [string, any][] = []) {
  15. this._keys = [];
  16. this._values = {};
  17. for (let i = 0; i < array.length; i++) {
  18. if (array[i] == null) continue; // skip null and undefined
  19. const entry = array[i];
  20. const key = entry[0];
  21. const value = entry[1];
  22. // Add the key to the list of keys in order
  23. this._keys.push(key);
  24. // Add the key and value to the values dictionary with a point
  25. // to the location in the ordered keys list
  26. this._values[key] = { v: value, i: this._keys.length - 1 };
  27. }
  28. }
  29. clear() {
  30. this._keys = [];
  31. this._values = {};
  32. }
  33. delete(key: string) {
  34. const value = this._values[key];
  35. if (value == null) return false;
  36. // Delete entry
  37. delete this._values[key];
  38. // Remove the key from the ordered keys list
  39. this._keys.splice(value.i, 1);
  40. return true;
  41. }
  42. entries() {
  43. let index = 0;
  44. return {
  45. next: () => {
  46. const key = this._keys[index++];
  47. return {
  48. value: key !== undefined ? [key, this._values[key].v] : undefined,
  49. done: key !== undefined ? false : true
  50. };
  51. }
  52. };
  53. }
  54. forEach(callback: (this: this, value: any, key: string, self: this) => void, self?: this) {
  55. self = self || this;
  56. for (let i = 0; i < this._keys.length; i++) {
  57. const key = this._keys[i];
  58. // Call the forEach callback
  59. callback.call(self, this._values[key].v, key, self);
  60. }
  61. }
  62. get(key: string) {
  63. return this._values[key] ? this._values[key].v : undefined;
  64. }
  65. has(key: string) {
  66. return this._values[key] != null;
  67. }
  68. keys() {
  69. let index = 0;
  70. return {
  71. next: () => {
  72. const key = this._keys[index++];
  73. return {
  74. value: key !== undefined ? key : undefined,
  75. done: key !== undefined ? false : true
  76. };
  77. }
  78. };
  79. }
  80. set(key: string, value: any) {
  81. if (this._values[key]) {
  82. this._values[key].v = value;
  83. return this;
  84. }
  85. // Add the key to the list of keys in order
  86. this._keys.push(key);
  87. // Add the key and value to the values dictionary with a point
  88. // to the location in the ordered keys list
  89. this._values[key] = { v: value, i: this._keys.length - 1 };
  90. return this;
  91. }
  92. values() {
  93. let index = 0;
  94. return {
  95. next: () => {
  96. const key = this._keys[index++];
  97. return {
  98. value: key !== undefined ? this._values[key].v : undefined,
  99. done: key !== undefined ? false : true
  100. };
  101. }
  102. };
  103. }
  104. get size() {
  105. return this._keys.length;
  106. }
  107. } as unknown as MapConstructor;
  108. }
  109. export { bsonMap as Map };