@rhombus-toolkit/collections 2.0.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,22 @@
1
+ /**
2
+ * A stack whose entries leave when their scope does.
3
+ *
4
+ * @remarks
5
+ * Iterates outermost first.
6
+ */
7
+ declare class AutoStack<T> implements Iterable<T> {
8
+ #private;
9
+ /** How many entries the stack holds. */
10
+ get length(): number;
11
+ /** Adds `item`; disposing the return truncates back to the pre-push depth, so an outer scope's dispose also drops what an inner one left. */
12
+ push(item: T): Disposable;
13
+ /** Whether `item` sits anywhere in the stack, not only at the top. */
14
+ has(item: T): boolean;
15
+ /** The innermost entry, absent where the stack holds nothing. */
16
+ peek(): T | undefined;
17
+ [Symbol.iterator](): ArrayIterator<T>;
18
+ }
19
+
1
20
  /**
2
21
  * A persistent singly-linked list — extending shares everything already there.
3
22
  *
@@ -30,6 +49,7 @@ declare class ImmutableLinkedList<T> implements Iterable<T> {
30
49
 
31
50
  declare class KindaWeakMap<K, V extends WeakKey> {
32
51
  #private;
52
+ /** An existing key keeps its place in iteration order, as with `Map`. */
33
53
  set(key: K, value: V): this;
34
54
  delete(key: K): boolean;
35
55
  get(key: K): V | undefined;
@@ -45,4 +65,4 @@ declare class KindaWeakMap<K, V extends WeakKey> {
45
65
  readonly [Symbol.toStringTag]: "KindaWeakMap";
46
66
  }
47
67
 
48
- export { ImmutableLinkedList, KindaWeakMap };
68
+ export { AutoStack, ImmutableLinkedList, KindaWeakMap };
@@ -1,3 +1,26 @@
1
+ // src/AutoStack.ts
2
+ class AutoStack {
3
+ #items = [];
4
+ get length() {
5
+ return this.#items.length;
6
+ }
7
+ push(item) {
8
+ const pos = this.#items.length;
9
+ this.#items.push(item);
10
+ return { [Symbol.dispose]: () => {
11
+ this.#items.length = pos;
12
+ } };
13
+ }
14
+ has(item) {
15
+ return this.#items.includes(item);
16
+ }
17
+ peek() {
18
+ return this.#items.at(-1);
19
+ }
20
+ [Symbol.iterator]() {
21
+ return this.#items.values();
22
+ }
23
+ }
1
24
  // src/ImmutableLinkedList.ts
2
25
  class ImmutableLinkedList {
3
26
  static #nothing = new ImmutableLinkedList(undefined, undefined, 0);
@@ -60,25 +83,29 @@ function tailOf(link) {
60
83
  // src/KindaWeakMap.ts
61
84
  class KindaWeakMap {
62
85
  #map = new Map;
63
- #registry = new FinalizationRegistry((key) => {
64
- if (this.#map.get(key)?.deref() === undefined) {
86
+ #registry = new FinalizationRegistry(({ key, ref }) => {
87
+ if (this.#map.get(key) === ref) {
65
88
  this.#map.delete(key);
66
89
  }
67
90
  });
68
91
  set(key, value) {
69
- this.delete(key);
70
- this.#registry.register(value, key, value);
71
- this.#map.set(key, new WeakRef(value));
92
+ const held = this.#map.get(key);
93
+ if (held) {
94
+ this.#registry.unregister(held);
95
+ }
96
+ const ref = new WeakRef(value);
97
+ this.#registry.register(value, { key, ref }, ref);
98
+ this.#map.set(key, ref);
72
99
  return this;
73
100
  }
74
101
  delete(key) {
75
- const value = this.get(key);
76
- this.#map.delete(key);
77
- if (value === undefined) {
102
+ const held = this.#map.get(key);
103
+ if (!held) {
78
104
  return false;
79
105
  }
80
- this.#registry.unregister(value);
81
- return true;
106
+ this.#map.delete(key);
107
+ this.#registry.unregister(held);
108
+ return held.deref() !== undefined;
82
109
  }
83
110
  get(key) {
84
111
  return this.#map.get(key)?.deref();
@@ -87,7 +114,7 @@ class KindaWeakMap {
87
114
  return this.get(key) !== undefined;
88
115
  }
89
116
  clear() {
90
- this.values().forEach((value) => this.#registry.unregister(value));
117
+ this.#map.forEach((ref) => this.#registry.unregister(ref));
91
118
  this.#map.clear();
92
119
  }
93
120
  forEach(callbackfn, thisArg) {
@@ -114,6 +141,7 @@ class KindaWeakMap {
114
141
  [Symbol.toStringTag] = "KindaWeakMap";
115
142
  }
116
143
  export {
144
+ AutoStack,
117
145
  ImmutableLinkedList,
118
146
  KindaWeakMap
119
147
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@rhombus-toolkit/collections",
3
- "version": "2.0.1",
4
- "description": "Collection data structures: ImmutableLinkedList (persistent, both ends known), KindaWeakMap (strong keys, weak values).",
3
+ "version": "2.1.0",
4
+ "description": "Collection data structures: AutoStack (entries leave with their scope), ImmutableLinkedList (persistent, both ends known), KindaWeakMap (strong keys, weak values).",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/rhombus-toolkit/ts.git",