@matter/general 0.14.0-alpha.0-20250603-af0cad2ff → 0.14.1-alpha.0-20250605-9fc134af0
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.
- package/dist/cjs/util/Set.d.ts +51 -0
- package/dist/cjs/util/Set.d.ts.map +1 -1
- package/dist/cjs/util/Set.js +122 -5
- package/dist/cjs/util/Set.js.map +2 -2
- package/dist/esm/util/Set.d.ts +51 -0
- package/dist/esm/util/Set.d.ts.map +1 -1
- package/dist/esm/util/Set.js +122 -5
- package/dist/esm/util/Set.js.map +2 -2
- package/package.json +2 -2
- package/src/util/Set.ts +156 -2
package/dist/cjs/util/Set.d.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Copyright 2022-2025 Matter.js Authors
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
+
import { ImplementationError } from "#MatterError.js";
|
|
6
7
|
import { Observable } from "./Observable.js";
|
|
7
8
|
/**
|
|
8
9
|
* A read-only set.
|
|
@@ -31,9 +32,19 @@ export interface ObservableSet<T> {
|
|
|
31
32
|
}
|
|
32
33
|
/**
|
|
33
34
|
* An interface for index set lookup.
|
|
35
|
+
*
|
|
36
|
+
* Note that this interface only supports a single item for each key. If multiple items associate with a key only the
|
|
37
|
+
* first is returned.
|
|
34
38
|
*/
|
|
35
39
|
export interface IndexedSet<T> {
|
|
40
|
+
/**
|
|
41
|
+
* Retrieve an item with the named {@link field} set to {@link value}.
|
|
42
|
+
*/
|
|
36
43
|
get<F extends keyof T>(field: F, value: T[F]): T | undefined;
|
|
44
|
+
/**
|
|
45
|
+
* Obtain a {@link Map} of values in {@link field} to the associated item in the set.
|
|
46
|
+
*/
|
|
47
|
+
mapOf<F extends keyof T>(field: F): Map<T[F], T>;
|
|
37
48
|
}
|
|
38
49
|
/**
|
|
39
50
|
* A generic set implementation supporting all interfaces in this module.
|
|
@@ -51,10 +62,50 @@ export declare class BasicSet<T, AddT = T> implements ImmutableSet<T>, MutableSe
|
|
|
51
62
|
has(item: T): boolean;
|
|
52
63
|
add(item: AddT): void;
|
|
53
64
|
get<F extends keyof T>(field: F, value: T[F]): T | undefined;
|
|
65
|
+
/**
|
|
66
|
+
* Obtain key/value map using specific field as key.
|
|
67
|
+
*
|
|
68
|
+
* Note we use {@link This} to constrain usage to sets where {@link T} === {@link AddT} as required by {@link Map}.
|
|
69
|
+
*/
|
|
70
|
+
mapOf<This extends BasicSet<T, T>, F extends keyof T>(this: This, field: F): Map<T[F], T>;
|
|
54
71
|
delete(item: T): boolean;
|
|
55
72
|
clear(): void;
|
|
56
73
|
get added(): Observable<[T], void>;
|
|
57
74
|
get deleted(): Observable<[T], void>;
|
|
58
75
|
protected create(definition: AddT): T;
|
|
59
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
* A {@link Map} backed by an {@link IndexedSet}.
|
|
79
|
+
*
|
|
80
|
+
* This supports the common case where sets must be looked up by key. Implementations like {@link BasicSet} offer
|
|
81
|
+
* efficient lookup by key using {@link IndexedSet#get}, but usage like a {@link Map} is still cumbersome. This class
|
|
82
|
+
* works as an adapter to make key/value access patterns more natural.
|
|
83
|
+
*/
|
|
84
|
+
export declare class MapOfIndexedSet<T, S extends ImmutableSet<T> & MutableSet<T> & IndexedSet<T>, K extends keyof T> implements Map<T[K], T> {
|
|
85
|
+
#private;
|
|
86
|
+
/**
|
|
87
|
+
* Create a new map.
|
|
88
|
+
*
|
|
89
|
+
* @param set the backing data
|
|
90
|
+
* @param key a property of {@link T} used as the key
|
|
91
|
+
* @param index optional index that optimizes lookup by bypassing {@link IndexedSet#get}
|
|
92
|
+
*/
|
|
93
|
+
constructor(set: S, key: K, index?: Map<T[K], T>);
|
|
94
|
+
clear(): void;
|
|
95
|
+
delete(key: T[K]): boolean;
|
|
96
|
+
forEach(callbackfn: (value: T, key: T[K], map: Map<T[K], T>) => void, thisArg?: any): void;
|
|
97
|
+
get(key: T[K]): T | undefined;
|
|
98
|
+
has(key: T[K]): boolean;
|
|
99
|
+
set(key: T[K], value: T): this;
|
|
100
|
+
get size(): number;
|
|
101
|
+
entries(): MapIterator<[T[K], T]>;
|
|
102
|
+
keys(): MapIterator<T[K]>;
|
|
103
|
+
values(): MapIterator<T>;
|
|
104
|
+
[Symbol.iterator](): MapIterator<[T[K], T]>;
|
|
105
|
+
[Symbol.toStringTag]: string;
|
|
106
|
+
}
|
|
107
|
+
export declare namespace MapOfIndexedSet {
|
|
108
|
+
class KeyValueMismatchError extends ImplementationError {
|
|
109
|
+
}
|
|
110
|
+
}
|
|
60
111
|
//# sourceMappingURL=Set.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Set.d.ts","sourceRoot":"","sources":["../../../src/util/Set.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C;;GAEG;AACH,MAAM,WAAW,YAAY,CAAC,CAAC;IAC3B,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,MAAM,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IAChD,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC;IACtB,IAAI,IAAI,IAAI,MAAM,CAAC;IACnB,IAAI,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,GAAG,SAAS,GAAG,CAAC,GAAG,SAAS,CAAC;IACjE,MAAM,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,GAAG,SAAS,GAAG,CAAC,EAAE,CAAC;CAC5D;AAED;;GAEG;AACH,MAAM,WAAW,UAAU,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC;IACnC,GAAG,CAAC,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC;IAC5B,MAAM,CAAC,UAAU,EAAE,CAAC,GAAG,OAAO,CAAC;IAC/B,KAAK,IAAI,IAAI,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa,CAAC,CAAC;IAC5B,IAAI,KAAK,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7B,IAAI,OAAO,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAClC;AAED
|
|
1
|
+
{"version":3,"file":"Set.d.ts","sourceRoot":"","sources":["../../../src/util/Set.ts"],"names":[],"mappings":"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"}
|
package/dist/cjs/util/Set.js
CHANGED
|
@@ -18,9 +18,11 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
var Set_exports = {};
|
|
20
20
|
__export(Set_exports, {
|
|
21
|
-
BasicSet: () => BasicSet
|
|
21
|
+
BasicSet: () => BasicSet,
|
|
22
|
+
MapOfIndexedSet: () => MapOfIndexedSet
|
|
22
23
|
});
|
|
23
24
|
module.exports = __toCommonJS(Set_exports);
|
|
25
|
+
var import_MatterError = require("#MatterError.js");
|
|
24
26
|
var import_Observable = require("./Observable.js");
|
|
25
27
|
/**
|
|
26
28
|
* @license
|
|
@@ -32,6 +34,7 @@ class BasicSet {
|
|
|
32
34
|
#added;
|
|
33
35
|
#deleted;
|
|
34
36
|
#indices;
|
|
37
|
+
#maps;
|
|
35
38
|
constructor(...initialItems) {
|
|
36
39
|
for (const item of initialItems) {
|
|
37
40
|
this.add(item);
|
|
@@ -87,6 +90,9 @@ class BasicSet {
|
|
|
87
90
|
this.#added?.emit(created);
|
|
88
91
|
}
|
|
89
92
|
get(field, value) {
|
|
93
|
+
return this.#indexOf(field).get(value);
|
|
94
|
+
}
|
|
95
|
+
#indexOf(field) {
|
|
90
96
|
if (!this.#indices) {
|
|
91
97
|
this.#indices = {};
|
|
92
98
|
}
|
|
@@ -94,15 +100,31 @@ class BasicSet {
|
|
|
94
100
|
if (index === void 0) {
|
|
95
101
|
index = /* @__PURE__ */ new Map();
|
|
96
102
|
for (const item of this) {
|
|
97
|
-
const
|
|
98
|
-
if (
|
|
103
|
+
const value = item[field];
|
|
104
|
+
if (value === void 0 || index.has(value)) {
|
|
99
105
|
continue;
|
|
100
106
|
}
|
|
101
|
-
index.set(
|
|
107
|
+
index.set(value, item);
|
|
102
108
|
}
|
|
103
109
|
this.#indices[field] = index;
|
|
104
110
|
}
|
|
105
|
-
return index
|
|
111
|
+
return index;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Obtain key/value map using specific field as key.
|
|
115
|
+
*
|
|
116
|
+
* Note we use {@link This} to constrain usage to sets where {@link T} === {@link AddT} as required by {@link Map}.
|
|
117
|
+
*/
|
|
118
|
+
mapOf(field) {
|
|
119
|
+
if (!this.#maps) {
|
|
120
|
+
this.#maps = {};
|
|
121
|
+
}
|
|
122
|
+
let map = this.#maps[field];
|
|
123
|
+
if (map === void 0) {
|
|
124
|
+
map = new MapOfIndexedSet(this, field, this.#indexOf(field));
|
|
125
|
+
this.#maps[field] = map;
|
|
126
|
+
}
|
|
127
|
+
return map;
|
|
106
128
|
}
|
|
107
129
|
delete(item) {
|
|
108
130
|
if (!this.#entries.delete(item)) {
|
|
@@ -142,4 +164,99 @@ class BasicSet {
|
|
|
142
164
|
return definition;
|
|
143
165
|
}
|
|
144
166
|
}
|
|
167
|
+
class MapOfIndexedSet {
|
|
168
|
+
#set;
|
|
169
|
+
#key;
|
|
170
|
+
// This is an optimization for lookup
|
|
171
|
+
#index;
|
|
172
|
+
/**
|
|
173
|
+
* Create a new map.
|
|
174
|
+
*
|
|
175
|
+
* @param set the backing data
|
|
176
|
+
* @param key a property of {@link T} used as the key
|
|
177
|
+
* @param index optional index that optimizes lookup by bypassing {@link IndexedSet#get}
|
|
178
|
+
*/
|
|
179
|
+
constructor(set, key, index) {
|
|
180
|
+
this.#set = set;
|
|
181
|
+
this.#key = key;
|
|
182
|
+
this.#index = index;
|
|
183
|
+
}
|
|
184
|
+
clear() {
|
|
185
|
+
this.#set.clear();
|
|
186
|
+
}
|
|
187
|
+
delete(key) {
|
|
188
|
+
const item = this.get(key);
|
|
189
|
+
if (item) {
|
|
190
|
+
return this.#set.delete(item);
|
|
191
|
+
}
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
forEach(callbackfn, thisArg) {
|
|
195
|
+
if (thisArg) {
|
|
196
|
+
callbackfn = callbackfn.bind(thisArg);
|
|
197
|
+
}
|
|
198
|
+
for (const [k, v] of this) {
|
|
199
|
+
callbackfn(v, k, this);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
get(key) {
|
|
203
|
+
if (this.#index) {
|
|
204
|
+
return this.#index.get(key);
|
|
205
|
+
}
|
|
206
|
+
return this.#set.get(this.#key, key);
|
|
207
|
+
}
|
|
208
|
+
has(key) {
|
|
209
|
+
return this.#index ? this.#index.has(key) : this.#set.get(this.#key, key) !== void 0;
|
|
210
|
+
}
|
|
211
|
+
set(key, value) {
|
|
212
|
+
if (value[this.#key] !== key) {
|
|
213
|
+
throw new MapOfIndexedSet.KeyValueMismatchError(
|
|
214
|
+
`Cannot set key "${key}" because value property ${String(this.#key)} is "${value[this.#key]}"`
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
if (this.has(key)) {
|
|
218
|
+
if (this.get(key) === value) {
|
|
219
|
+
return this;
|
|
220
|
+
}
|
|
221
|
+
this.#set.delete(this.#index ? this.#index.get(key) : this.#set.get(this.#key, key));
|
|
222
|
+
}
|
|
223
|
+
this.#set.add(value);
|
|
224
|
+
return this;
|
|
225
|
+
}
|
|
226
|
+
get size() {
|
|
227
|
+
return this.#set.size;
|
|
228
|
+
}
|
|
229
|
+
entries() {
|
|
230
|
+
return this[Symbol.iterator]();
|
|
231
|
+
}
|
|
232
|
+
keys() {
|
|
233
|
+
if (this.#index) {
|
|
234
|
+
return this.#index.keys();
|
|
235
|
+
}
|
|
236
|
+
const keys = [...this.#set].map((item) => item[this.#key]).filter((key) => key !== void 0);
|
|
237
|
+
return keys[Symbol.iterator]();
|
|
238
|
+
}
|
|
239
|
+
values() {
|
|
240
|
+
if (this.#index) {
|
|
241
|
+
return this.#index.values();
|
|
242
|
+
}
|
|
243
|
+
const values = [...this.#set].map((item) => item);
|
|
244
|
+
return values[Symbol.iterator]();
|
|
245
|
+
}
|
|
246
|
+
*[Symbol.iterator]() {
|
|
247
|
+
for (const item of this.#set) {
|
|
248
|
+
const k = item[this.#key];
|
|
249
|
+
if (k === void 0) {
|
|
250
|
+
continue;
|
|
251
|
+
}
|
|
252
|
+
yield [k, item];
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
[Symbol.toStringTag] = "Map";
|
|
256
|
+
}
|
|
257
|
+
((MapOfIndexedSet2) => {
|
|
258
|
+
class KeyValueMismatchError extends import_MatterError.ImplementationError {
|
|
259
|
+
}
|
|
260
|
+
MapOfIndexedSet2.KeyValueMismatchError = KeyValueMismatchError;
|
|
261
|
+
})(MapOfIndexedSet || (MapOfIndexedSet = {}));
|
|
145
262
|
//# sourceMappingURL=Set.js.map
|
package/dist/cjs/util/Set.js.map
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/util/Set.ts"],
|
|
4
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,wBAA2B;
|
|
5
|
-
"names": ["
|
|
4
|
+
"mappings": "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",
|
|
5
|
+
"names": ["MapOfIndexedSet"]
|
|
6
6
|
}
|
package/dist/esm/util/Set.d.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Copyright 2022-2025 Matter.js Authors
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
+
import { ImplementationError } from "#MatterError.js";
|
|
6
7
|
import { Observable } from "./Observable.js";
|
|
7
8
|
/**
|
|
8
9
|
* A read-only set.
|
|
@@ -31,9 +32,19 @@ export interface ObservableSet<T> {
|
|
|
31
32
|
}
|
|
32
33
|
/**
|
|
33
34
|
* An interface for index set lookup.
|
|
35
|
+
*
|
|
36
|
+
* Note that this interface only supports a single item for each key. If multiple items associate with a key only the
|
|
37
|
+
* first is returned.
|
|
34
38
|
*/
|
|
35
39
|
export interface IndexedSet<T> {
|
|
40
|
+
/**
|
|
41
|
+
* Retrieve an item with the named {@link field} set to {@link value}.
|
|
42
|
+
*/
|
|
36
43
|
get<F extends keyof T>(field: F, value: T[F]): T | undefined;
|
|
44
|
+
/**
|
|
45
|
+
* Obtain a {@link Map} of values in {@link field} to the associated item in the set.
|
|
46
|
+
*/
|
|
47
|
+
mapOf<F extends keyof T>(field: F): Map<T[F], T>;
|
|
37
48
|
}
|
|
38
49
|
/**
|
|
39
50
|
* A generic set implementation supporting all interfaces in this module.
|
|
@@ -51,10 +62,50 @@ export declare class BasicSet<T, AddT = T> implements ImmutableSet<T>, MutableSe
|
|
|
51
62
|
has(item: T): boolean;
|
|
52
63
|
add(item: AddT): void;
|
|
53
64
|
get<F extends keyof T>(field: F, value: T[F]): T | undefined;
|
|
65
|
+
/**
|
|
66
|
+
* Obtain key/value map using specific field as key.
|
|
67
|
+
*
|
|
68
|
+
* Note we use {@link This} to constrain usage to sets where {@link T} === {@link AddT} as required by {@link Map}.
|
|
69
|
+
*/
|
|
70
|
+
mapOf<This extends BasicSet<T, T>, F extends keyof T>(this: This, field: F): Map<T[F], T>;
|
|
54
71
|
delete(item: T): boolean;
|
|
55
72
|
clear(): void;
|
|
56
73
|
get added(): Observable<[T], void>;
|
|
57
74
|
get deleted(): Observable<[T], void>;
|
|
58
75
|
protected create(definition: AddT): T;
|
|
59
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
* A {@link Map} backed by an {@link IndexedSet}.
|
|
79
|
+
*
|
|
80
|
+
* This supports the common case where sets must be looked up by key. Implementations like {@link BasicSet} offer
|
|
81
|
+
* efficient lookup by key using {@link IndexedSet#get}, but usage like a {@link Map} is still cumbersome. This class
|
|
82
|
+
* works as an adapter to make key/value access patterns more natural.
|
|
83
|
+
*/
|
|
84
|
+
export declare class MapOfIndexedSet<T, S extends ImmutableSet<T> & MutableSet<T> & IndexedSet<T>, K extends keyof T> implements Map<T[K], T> {
|
|
85
|
+
#private;
|
|
86
|
+
/**
|
|
87
|
+
* Create a new map.
|
|
88
|
+
*
|
|
89
|
+
* @param set the backing data
|
|
90
|
+
* @param key a property of {@link T} used as the key
|
|
91
|
+
* @param index optional index that optimizes lookup by bypassing {@link IndexedSet#get}
|
|
92
|
+
*/
|
|
93
|
+
constructor(set: S, key: K, index?: Map<T[K], T>);
|
|
94
|
+
clear(): void;
|
|
95
|
+
delete(key: T[K]): boolean;
|
|
96
|
+
forEach(callbackfn: (value: T, key: T[K], map: Map<T[K], T>) => void, thisArg?: any): void;
|
|
97
|
+
get(key: T[K]): T | undefined;
|
|
98
|
+
has(key: T[K]): boolean;
|
|
99
|
+
set(key: T[K], value: T): this;
|
|
100
|
+
get size(): number;
|
|
101
|
+
entries(): MapIterator<[T[K], T]>;
|
|
102
|
+
keys(): MapIterator<T[K]>;
|
|
103
|
+
values(): MapIterator<T>;
|
|
104
|
+
[Symbol.iterator](): MapIterator<[T[K], T]>;
|
|
105
|
+
[Symbol.toStringTag]: string;
|
|
106
|
+
}
|
|
107
|
+
export declare namespace MapOfIndexedSet {
|
|
108
|
+
class KeyValueMismatchError extends ImplementationError {
|
|
109
|
+
}
|
|
110
|
+
}
|
|
60
111
|
//# sourceMappingURL=Set.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Set.d.ts","sourceRoot":"","sources":["../../../src/util/Set.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C;;GAEG;AACH,MAAM,WAAW,YAAY,CAAC,CAAC;IAC3B,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,MAAM,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IAChD,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC;IACtB,IAAI,IAAI,IAAI,MAAM,CAAC;IACnB,IAAI,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,GAAG,SAAS,GAAG,CAAC,GAAG,SAAS,CAAC;IACjE,MAAM,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,GAAG,SAAS,GAAG,CAAC,EAAE,CAAC;CAC5D;AAED;;GAEG;AACH,MAAM,WAAW,UAAU,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC;IACnC,GAAG,CAAC,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC;IAC5B,MAAM,CAAC,UAAU,EAAE,CAAC,GAAG,OAAO,CAAC;IAC/B,KAAK,IAAI,IAAI,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa,CAAC,CAAC;IAC5B,IAAI,KAAK,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7B,IAAI,OAAO,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAClC;AAED
|
|
1
|
+
{"version":3,"file":"Set.d.ts","sourceRoot":"","sources":["../../../src/util/Set.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/util/Set.js
CHANGED
|
@@ -3,12 +3,14 @@
|
|
|
3
3
|
* Copyright 2022-2025 Matter.js Authors
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
+
import { ImplementationError } from "#MatterError.js";
|
|
6
7
|
import { Observable } from "./Observable.js";
|
|
7
8
|
class BasicSet {
|
|
8
9
|
#entries = /* @__PURE__ */ new Set();
|
|
9
10
|
#added;
|
|
10
11
|
#deleted;
|
|
11
12
|
#indices;
|
|
13
|
+
#maps;
|
|
12
14
|
constructor(...initialItems) {
|
|
13
15
|
for (const item of initialItems) {
|
|
14
16
|
this.add(item);
|
|
@@ -64,6 +66,9 @@ class BasicSet {
|
|
|
64
66
|
this.#added?.emit(created);
|
|
65
67
|
}
|
|
66
68
|
get(field, value) {
|
|
69
|
+
return this.#indexOf(field).get(value);
|
|
70
|
+
}
|
|
71
|
+
#indexOf(field) {
|
|
67
72
|
if (!this.#indices) {
|
|
68
73
|
this.#indices = {};
|
|
69
74
|
}
|
|
@@ -71,15 +76,31 @@ class BasicSet {
|
|
|
71
76
|
if (index === void 0) {
|
|
72
77
|
index = /* @__PURE__ */ new Map();
|
|
73
78
|
for (const item of this) {
|
|
74
|
-
const
|
|
75
|
-
if (
|
|
79
|
+
const value = item[field];
|
|
80
|
+
if (value === void 0 || index.has(value)) {
|
|
76
81
|
continue;
|
|
77
82
|
}
|
|
78
|
-
index.set(
|
|
83
|
+
index.set(value, item);
|
|
79
84
|
}
|
|
80
85
|
this.#indices[field] = index;
|
|
81
86
|
}
|
|
82
|
-
return index
|
|
87
|
+
return index;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Obtain key/value map using specific field as key.
|
|
91
|
+
*
|
|
92
|
+
* Note we use {@link This} to constrain usage to sets where {@link T} === {@link AddT} as required by {@link Map}.
|
|
93
|
+
*/
|
|
94
|
+
mapOf(field) {
|
|
95
|
+
if (!this.#maps) {
|
|
96
|
+
this.#maps = {};
|
|
97
|
+
}
|
|
98
|
+
let map = this.#maps[field];
|
|
99
|
+
if (map === void 0) {
|
|
100
|
+
map = new MapOfIndexedSet(this, field, this.#indexOf(field));
|
|
101
|
+
this.#maps[field] = map;
|
|
102
|
+
}
|
|
103
|
+
return map;
|
|
83
104
|
}
|
|
84
105
|
delete(item) {
|
|
85
106
|
if (!this.#entries.delete(item)) {
|
|
@@ -119,7 +140,103 @@ class BasicSet {
|
|
|
119
140
|
return definition;
|
|
120
141
|
}
|
|
121
142
|
}
|
|
143
|
+
class MapOfIndexedSet {
|
|
144
|
+
#set;
|
|
145
|
+
#key;
|
|
146
|
+
// This is an optimization for lookup
|
|
147
|
+
#index;
|
|
148
|
+
/**
|
|
149
|
+
* Create a new map.
|
|
150
|
+
*
|
|
151
|
+
* @param set the backing data
|
|
152
|
+
* @param key a property of {@link T} used as the key
|
|
153
|
+
* @param index optional index that optimizes lookup by bypassing {@link IndexedSet#get}
|
|
154
|
+
*/
|
|
155
|
+
constructor(set, key, index) {
|
|
156
|
+
this.#set = set;
|
|
157
|
+
this.#key = key;
|
|
158
|
+
this.#index = index;
|
|
159
|
+
}
|
|
160
|
+
clear() {
|
|
161
|
+
this.#set.clear();
|
|
162
|
+
}
|
|
163
|
+
delete(key) {
|
|
164
|
+
const item = this.get(key);
|
|
165
|
+
if (item) {
|
|
166
|
+
return this.#set.delete(item);
|
|
167
|
+
}
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
forEach(callbackfn, thisArg) {
|
|
171
|
+
if (thisArg) {
|
|
172
|
+
callbackfn = callbackfn.bind(thisArg);
|
|
173
|
+
}
|
|
174
|
+
for (const [k, v] of this) {
|
|
175
|
+
callbackfn(v, k, this);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
get(key) {
|
|
179
|
+
if (this.#index) {
|
|
180
|
+
return this.#index.get(key);
|
|
181
|
+
}
|
|
182
|
+
return this.#set.get(this.#key, key);
|
|
183
|
+
}
|
|
184
|
+
has(key) {
|
|
185
|
+
return this.#index ? this.#index.has(key) : this.#set.get(this.#key, key) !== void 0;
|
|
186
|
+
}
|
|
187
|
+
set(key, value) {
|
|
188
|
+
if (value[this.#key] !== key) {
|
|
189
|
+
throw new MapOfIndexedSet.KeyValueMismatchError(
|
|
190
|
+
`Cannot set key "${key}" because value property ${String(this.#key)} is "${value[this.#key]}"`
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
if (this.has(key)) {
|
|
194
|
+
if (this.get(key) === value) {
|
|
195
|
+
return this;
|
|
196
|
+
}
|
|
197
|
+
this.#set.delete(this.#index ? this.#index.get(key) : this.#set.get(this.#key, key));
|
|
198
|
+
}
|
|
199
|
+
this.#set.add(value);
|
|
200
|
+
return this;
|
|
201
|
+
}
|
|
202
|
+
get size() {
|
|
203
|
+
return this.#set.size;
|
|
204
|
+
}
|
|
205
|
+
entries() {
|
|
206
|
+
return this[Symbol.iterator]();
|
|
207
|
+
}
|
|
208
|
+
keys() {
|
|
209
|
+
if (this.#index) {
|
|
210
|
+
return this.#index.keys();
|
|
211
|
+
}
|
|
212
|
+
const keys = [...this.#set].map((item) => item[this.#key]).filter((key) => key !== void 0);
|
|
213
|
+
return keys[Symbol.iterator]();
|
|
214
|
+
}
|
|
215
|
+
values() {
|
|
216
|
+
if (this.#index) {
|
|
217
|
+
return this.#index.values();
|
|
218
|
+
}
|
|
219
|
+
const values = [...this.#set].map((item) => item);
|
|
220
|
+
return values[Symbol.iterator]();
|
|
221
|
+
}
|
|
222
|
+
*[Symbol.iterator]() {
|
|
223
|
+
for (const item of this.#set) {
|
|
224
|
+
const k = item[this.#key];
|
|
225
|
+
if (k === void 0) {
|
|
226
|
+
continue;
|
|
227
|
+
}
|
|
228
|
+
yield [k, item];
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
[Symbol.toStringTag] = "Map";
|
|
232
|
+
}
|
|
233
|
+
((MapOfIndexedSet2) => {
|
|
234
|
+
class KeyValueMismatchError extends ImplementationError {
|
|
235
|
+
}
|
|
236
|
+
MapOfIndexedSet2.KeyValueMismatchError = KeyValueMismatchError;
|
|
237
|
+
})(MapOfIndexedSet || (MapOfIndexedSet = {}));
|
|
122
238
|
export {
|
|
123
|
-
BasicSet
|
|
239
|
+
BasicSet,
|
|
240
|
+
MapOfIndexedSet
|
|
124
241
|
};
|
|
125
242
|
//# sourceMappingURL=Set.js.map
|
package/dist/esm/util/Set.js.map
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/util/Set.ts"],
|
|
4
|
-
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,SAAS,kBAAkB;
|
|
5
|
-
"names": ["
|
|
4
|
+
"mappings": "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",
|
|
5
|
+
"names": ["MapOfIndexedSet"]
|
|
6
6
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@matter/general",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.1-alpha.0-20250605-9fc134af0",
|
|
4
4
|
"description": "Non-Matter support for Matter.js",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"iot",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"@noble/curves": "^1.9.1"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@matter/testing": "0.14.
|
|
39
|
+
"@matter/testing": "0.14.1-alpha.0-20250605-9fc134af0"
|
|
40
40
|
},
|
|
41
41
|
"files": [
|
|
42
42
|
"dist/**/*",
|
package/src/util/Set.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import { ImplementationError } from "#MatterError.js";
|
|
7
8
|
import { Observable } from "./Observable.js";
|
|
8
9
|
|
|
9
10
|
/**
|
|
@@ -36,9 +37,20 @@ export interface ObservableSet<T> {
|
|
|
36
37
|
|
|
37
38
|
/**
|
|
38
39
|
* An interface for index set lookup.
|
|
40
|
+
*
|
|
41
|
+
* Note that this interface only supports a single item for each key. If multiple items associate with a key only the
|
|
42
|
+
* first is returned.
|
|
39
43
|
*/
|
|
40
44
|
export interface IndexedSet<T> {
|
|
45
|
+
/**
|
|
46
|
+
* Retrieve an item with the named {@link field} set to {@link value}.
|
|
47
|
+
*/
|
|
41
48
|
get<F extends keyof T>(field: F, value: T[F]): T | undefined;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Obtain a {@link Map} of values in {@link field} to the associated item in the set.
|
|
52
|
+
*/
|
|
53
|
+
mapOf<F extends keyof T>(field: F): Map<T[F], T>;
|
|
42
54
|
}
|
|
43
55
|
|
|
44
56
|
/**
|
|
@@ -51,7 +63,10 @@ export class BasicSet<T, AddT = T> implements ImmutableSet<T>, MutableSet<T, Add
|
|
|
51
63
|
#added?: Observable<[T]>;
|
|
52
64
|
#deleted?: Observable<[T]>;
|
|
53
65
|
#indices?: {
|
|
54
|
-
[field in keyof T]?: Map<
|
|
66
|
+
[field in keyof T]?: Map<T[field], T>;
|
|
67
|
+
};
|
|
68
|
+
#maps?: {
|
|
69
|
+
[field in keyof T]?: Map<T[field], T>;
|
|
55
70
|
};
|
|
56
71
|
|
|
57
72
|
constructor(...initialItems: AddT[]) {
|
|
@@ -123,6 +138,10 @@ export class BasicSet<T, AddT = T> implements ImmutableSet<T>, MutableSet<T, Add
|
|
|
123
138
|
}
|
|
124
139
|
|
|
125
140
|
get<F extends keyof T>(field: F, value: T[F]) {
|
|
141
|
+
return this.#indexOf(field).get(value);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
#indexOf<F extends keyof T>(field: F) {
|
|
126
145
|
if (!this.#indices) {
|
|
127
146
|
this.#indices = {};
|
|
128
147
|
}
|
|
@@ -138,7 +157,24 @@ export class BasicSet<T, AddT = T> implements ImmutableSet<T>, MutableSet<T, Add
|
|
|
138
157
|
}
|
|
139
158
|
this.#indices[field] = index;
|
|
140
159
|
}
|
|
141
|
-
return index
|
|
160
|
+
return index!; // Need "!" due to (apparent) TS bug
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Obtain key/value map using specific field as key.
|
|
165
|
+
*
|
|
166
|
+
* Note we use {@link This} to constrain usage to sets where {@link T} === {@link AddT} as required by {@link Map}.
|
|
167
|
+
*/
|
|
168
|
+
mapOf<This extends BasicSet<T, T>, F extends keyof T>(this: This, field: F): Map<T[F], T> {
|
|
169
|
+
if (!this.#maps) {
|
|
170
|
+
this.#maps = {};
|
|
171
|
+
}
|
|
172
|
+
let map = this.#maps[field];
|
|
173
|
+
if (map === undefined) {
|
|
174
|
+
map = new MapOfIndexedSet(this, field, this.#indexOf(field));
|
|
175
|
+
this.#maps[field] = map;
|
|
176
|
+
}
|
|
177
|
+
return map;
|
|
142
178
|
}
|
|
143
179
|
|
|
144
180
|
delete(item: T) {
|
|
@@ -187,3 +223,121 @@ export class BasicSet<T, AddT = T> implements ImmutableSet<T>, MutableSet<T, Add
|
|
|
187
223
|
return definition as unknown as T;
|
|
188
224
|
}
|
|
189
225
|
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* A {@link Map} backed by an {@link IndexedSet}.
|
|
229
|
+
*
|
|
230
|
+
* This supports the common case where sets must be looked up by key. Implementations like {@link BasicSet} offer
|
|
231
|
+
* efficient lookup by key using {@link IndexedSet#get}, but usage like a {@link Map} is still cumbersome. This class
|
|
232
|
+
* works as an adapter to make key/value access patterns more natural.
|
|
233
|
+
*/
|
|
234
|
+
export class MapOfIndexedSet<T, S extends ImmutableSet<T> & MutableSet<T> & IndexedSet<T>, K extends keyof T>
|
|
235
|
+
implements Map<T[K], T>
|
|
236
|
+
{
|
|
237
|
+
#set: S;
|
|
238
|
+
#key: K;
|
|
239
|
+
|
|
240
|
+
// This is an optimization for lookup
|
|
241
|
+
#index?: Map<T[K], T>;
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Create a new map.
|
|
245
|
+
*
|
|
246
|
+
* @param set the backing data
|
|
247
|
+
* @param key a property of {@link T} used as the key
|
|
248
|
+
* @param index optional index that optimizes lookup by bypassing {@link IndexedSet#get}
|
|
249
|
+
*/
|
|
250
|
+
constructor(set: S, key: K, index?: Map<T[K], T>) {
|
|
251
|
+
this.#set = set;
|
|
252
|
+
this.#key = key;
|
|
253
|
+
this.#index = index;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
clear(): void {
|
|
257
|
+
this.#set.clear();
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
delete(key: T[K]): boolean {
|
|
261
|
+
const item = this.get(key);
|
|
262
|
+
if (item) {
|
|
263
|
+
return this.#set.delete(item);
|
|
264
|
+
}
|
|
265
|
+
return false;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
forEach(callbackfn: (value: T, key: T[K], map: Map<T[K], T>) => void, thisArg?: any): void {
|
|
269
|
+
if (thisArg) {
|
|
270
|
+
callbackfn = callbackfn.bind(thisArg);
|
|
271
|
+
}
|
|
272
|
+
for (const [k, v] of this) {
|
|
273
|
+
callbackfn(v, k, this);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
get(key: T[K]): T | undefined {
|
|
278
|
+
if (this.#index) {
|
|
279
|
+
return this.#index.get(key);
|
|
280
|
+
}
|
|
281
|
+
return this.#set.get(this.#key, key);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
has(key: T[K]): boolean {
|
|
285
|
+
return this.#index ? this.#index.has(key) : this.#set.get(this.#key, key) !== undefined;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
set(key: T[K], value: T): this {
|
|
289
|
+
if (value[this.#key] !== key) {
|
|
290
|
+
throw new MapOfIndexedSet.KeyValueMismatchError(
|
|
291
|
+
`Cannot set key "${key}" because value property ${String(this.#key)} is "${value[this.#key]}"`,
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
if (this.has(key)) {
|
|
295
|
+
if (this.get(key) === value) {
|
|
296
|
+
return this;
|
|
297
|
+
}
|
|
298
|
+
this.#set.delete((this.#index ? this.#index.get(key) : this.#set.get(this.#key, key)) as T);
|
|
299
|
+
}
|
|
300
|
+
this.#set.add(value);
|
|
301
|
+
return this;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
get size() {
|
|
305
|
+
return this.#set.size;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
entries(): MapIterator<[T[K], T]> {
|
|
309
|
+
return this[Symbol.iterator]();
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
keys(): MapIterator<T[K]> {
|
|
313
|
+
if (this.#index) {
|
|
314
|
+
return this.#index.keys();
|
|
315
|
+
}
|
|
316
|
+
const keys = [...this.#set].map(item => item[this.#key]).filter(key => key !== undefined);
|
|
317
|
+
return keys[Symbol.iterator]();
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
values(): MapIterator<T> {
|
|
321
|
+
if (this.#index) {
|
|
322
|
+
return this.#index.values();
|
|
323
|
+
}
|
|
324
|
+
const values = [...this.#set].map(item => item);
|
|
325
|
+
return values[Symbol.iterator]();
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
*[Symbol.iterator](): MapIterator<[T[K], T]> {
|
|
329
|
+
for (const item of this.#set) {
|
|
330
|
+
const k = item[this.#key];
|
|
331
|
+
if (k === undefined) {
|
|
332
|
+
continue;
|
|
333
|
+
}
|
|
334
|
+
yield [k, item];
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
[Symbol.toStringTag] = "Map";
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
export namespace MapOfIndexedSet {
|
|
342
|
+
export class KeyValueMismatchError extends ImplementationError {}
|
|
343
|
+
}
|