• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Minhir / multikeys / 17218453029

25 Aug 2025 07:18PM UTC coverage: 97.555% (-2.4%) from 100.0%
17218453029

Pull #41

github

web-flow
Merge 5f65e2921 into 16c42e606
Pull Request #41: Use vitest

106 of 108 branches covered (98.15%)

Branch coverage included in aggregate %.

293 of 301 relevant lines covered (97.34%)

113.21 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.62
/src/mkweakmap.ts
1
import { getLastValueHandler, type WeakValueHandler } from "./utils";
1✔
2

3
function createNewValueHandler<K extends object, V>(): WeakValueHandler<K, V> {
97✔
4
  return {
97✔
5
    next: new WeakMap(),
97✔
6
  };
97✔
7
}
97✔
8

9
class MKWeakMap<K extends object = object, V = any> {
1✔
10
  private _root = createNewValueHandler<K, V>();
1✔
11

12
  /**
13
   * Creates a new MKWeakMap object.
14
   *
15
   * Could be called with initial keys-values
16
   *
17
   * ```
18
   * const empty = new MKWeakMap();
19
   * const withValues = new MKWeakMap([
20
   *     [[{foo: 'bar'}], 'val']
21
   * ]);
22
   * ```
23
   */
24
  constructor(iterable?: Iterable<readonly [readonly K[], V]>) {
1✔
25
    if (!iterable) {
16✔
26
      return;
12✔
27
    }
12✔
28

29
    for (const [keys, value] of iterable) {
9✔
30
      this.set(keys, value);
20✔
31
    }
20✔
32
  }
16✔
33

34
  /**
35
   * Removes any value associated to the keys. Returns true if an element in the MKWeakMap object has been removed successfully.
36
   *
37
   * ```
38
   * const obj = {};
39
   * const mkWeakMap = new MKWeakMap([[obj, 'foo']]);
40
   *
41
   * mkWeakMap.delete([obj]); // => true
42
   * mkWeakMap.delete([obj]); // => false
43
   * ```
44
   */
45
  delete(keys: readonly K[]): boolean {
1✔
46
    const len = keys.length;
26✔
47

48
    const f = (handler: WeakValueHandler<K, V>, ind: number): boolean => {
26✔
49
      if (ind === len) {
76✔
50
        if (!handler.hasOwnProperty("val")) {
24✔
51
          return false;
2✔
52
        }
2✔
53

54
        delete handler["val"];
22✔
55

56
        return true;
22✔
57
      }
22✔
58

59
      const key = keys[ind];
52✔
60
      const nextHandler = handler.next.get(key);
52✔
61

62
      if (!nextHandler) {
76✔
63
        return false;
2✔
64
      }
2✔
65

66
      return f(nextHandler, ind + 1);
50✔
67
    };
76✔
68

69
    return f(this._root, 0);
26✔
70
  }
26✔
71

72
  /**
73
   * Returns the value associated to the keys, or undefined if there is none.
74
   *
75
   * ```
76
   * const obj = {};
77
   * const mkWeakMap = new MKWeakMap([[obj, 'foo']]);
78
   *
79
   * mkWeakMap.get([obj]); // => 'foo'
80
   * ```
81
   */
82
  get(keys: readonly K[]): V | undefined {
1✔
83
    const handler = getLastValueHandler(this._root, keys);
26✔
84

85
    return handler?.val;
26✔
86
  }
26✔
87

88
  /**
89
   * Returns a Boolean asserting whether a value has been associated to the keys in the MKWeakMap object or not.
90
   *
91
   * ```
92
   * const obj = {};
93
   * const mkWeakMap = new MKWeakMap([[obj, 'foo']]);
94
   *
95
   * mkWeakMap.has([obj]); // => 'true'
96
   * ```
97
   */
98
  has(keys: readonly K[]): boolean {
1✔
99
    const handler = getLastValueHandler(this._root, keys);
80✔
100

101
    return handler ? handler.hasOwnProperty("val") : false;
80✔
102
  }
80✔
103

104
  /**
105
   * Sets the value for the keys in the MKWeakMap object. Returns the MKWeakMap object.
106
   *
107
   * ```
108
   * const mkWeakMap = new MKWeakMap();
109
   * const obj = {};
110
   *
111
   * mkWeakMap.set([obj], 'foo');
112
   * mkWeakMap.get([obj]); // => 'foo'
113
   * ```
114
   */
115
  set(keys: readonly K[], value: V): this {
1✔
116
    if (!Array.isArray(keys)) {
59✔
117
      throw new Error("Keys should be an array");
4✔
118
    }
4✔
119

120
    for (const key of keys) {
59✔
121
      if (key !== Object(key)) {
115✔
122
        throw new Error("Invalid value is used as weak key");
4✔
123
      }
4✔
124
    }
115✔
125

126
    const handler = getLastValueHandler(
51✔
127
      this._root,
51✔
128
      keys,
51✔
129
      createNewValueHandler,
51✔
130
    );
51✔
131

132
    /* istanbul ignore next */
133
    if (!handler) {
59!
134
      throw new Error(
×
135
        "Multikeys: can't set keys. There is some internal problem.",
×
136
      ); // Should never be called
×
137
    }
✔
138

139
    handler.val = value;
51✔
140

141
    return this;
51✔
142
  }
59✔
143
}
1✔
144

145
export default MKWeakMap;
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc