@companion-surface/base 0.6.0 → 0.6.2
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/CHANGELOG.md +14 -0
- package/dist/__tests__/util.test.d.ts +2 -0
- package/dist/__tests__/util.test.d.ts.map +1 -0
- package/dist/__tests__/util.test.js +213 -0
- package/dist/__tests__/util.test.js.map +1 -0
- package/dist/surface-api/types.d.ts +5 -1
- package/dist/surface-api/types.d.ts.map +1 -1
- package/dist/util.d.ts +21 -0
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +66 -0
- package/dist/util.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.6.2](https://github.com/bitfocus/companion-surface-api/compare/companion-surface-base-v0.6.1...companion-surface-base-v0.6.2) (2025-11-25)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* rework serialnumber generator to support tracking across runs ([c047e11](https://github.com/bitfocus/companion-surface-api/commit/c047e1139b535e4ecc8d15ff100b4006c5508363))
|
|
9
|
+
|
|
10
|
+
## [0.6.1](https://github.com/bitfocus/companion-surface-api/compare/companion-surface-base-v0.6.0...companion-surface-base-v0.6.1) (2025-11-24)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* make serialnumber always defined, and add helper for generating unique serials ([2cfc41e](https://github.com/bitfocus/companion-surface-api/commit/2cfc41ed58487a5d0bab7b6c6aa110774b1bf907))
|
|
16
|
+
|
|
3
17
|
## [0.6.0](https://github.com/bitfocus/companion-surface-api/compare/companion-surface-base-v0.5.0...companion-surface-base-v0.6.0) (2025-11-23)
|
|
4
18
|
|
|
5
19
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/util.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { describe, expect, test } from 'vitest';
|
|
2
|
+
import { StableDeviceIdGenerator } from '../util.js';
|
|
3
|
+
describe('StableDeviceIdGenerator', () => {
|
|
4
|
+
test('generates different IDs for different uniqueness keys', () => {
|
|
5
|
+
const generator = new StableDeviceIdGenerator();
|
|
6
|
+
const id1 = generator.generateId('1234:5678', '/dev/hidraw0');
|
|
7
|
+
const id2 = generator.generateId('1234:9999', '/dev/hidraw1');
|
|
8
|
+
expect(id1).not.toBe(id2);
|
|
9
|
+
expect(id1).toHaveLength(40); // SHA1 hex digest length
|
|
10
|
+
expect(id2).toHaveLength(40);
|
|
11
|
+
});
|
|
12
|
+
test('generates different IDs for same uniqueness key with different paths', () => {
|
|
13
|
+
const generator = new StableDeviceIdGenerator();
|
|
14
|
+
const id1 = generator.generateId('1234:5678', '/dev/hidraw0');
|
|
15
|
+
const id2 = generator.generateId('1234:5678', '/dev/hidraw1');
|
|
16
|
+
expect(id1).not.toBe(id2);
|
|
17
|
+
});
|
|
18
|
+
test('returns same ID for same device path on repeated calls', () => {
|
|
19
|
+
const generator = new StableDeviceIdGenerator();
|
|
20
|
+
const id1 = generator.generateId('1234:5678', '/dev/hidraw0');
|
|
21
|
+
const id2 = generator.generateId('1234:5678', '/dev/hidraw0');
|
|
22
|
+
expect(id1).toBe(id2);
|
|
23
|
+
});
|
|
24
|
+
test('generates stable IDs with counter increment', () => {
|
|
25
|
+
const generator = new StableDeviceIdGenerator();
|
|
26
|
+
const id1 = generator.generateId('1234:5678', '/dev/hidraw0');
|
|
27
|
+
const id2 = generator.generateId('1234:5678', '/dev/hidraw1');
|
|
28
|
+
const id3 = generator.generateId('1234:5678', '/dev/hidraw2');
|
|
29
|
+
// All should be unique
|
|
30
|
+
expect(new Set([id1, id2, id3]).size).toBe(3);
|
|
31
|
+
});
|
|
32
|
+
test('separate instances have independent state', () => {
|
|
33
|
+
const generator1 = new StableDeviceIdGenerator();
|
|
34
|
+
const generator2 = new StableDeviceIdGenerator();
|
|
35
|
+
const id1 = generator1.generateId('1234:5678', '/dev/hidraw0');
|
|
36
|
+
const id2 = generator2.generateId('1234:5678', '/dev/hidraw1');
|
|
37
|
+
// Same inputs in different instances should produce same ID
|
|
38
|
+
expect(id1).toBe(id2);
|
|
39
|
+
});
|
|
40
|
+
test('handles multiple devices with same uniqueness key in batch', () => {
|
|
41
|
+
const generator = new StableDeviceIdGenerator();
|
|
42
|
+
// Simulate 3 identical devices (same vendor/product) with different paths
|
|
43
|
+
const ids = [
|
|
44
|
+
generator.generateId('1234:5678', '/dev/hidraw0'),
|
|
45
|
+
generator.generateId('1234:5678', '/dev/hidraw1'),
|
|
46
|
+
generator.generateId('1234:5678', '/dev/hidraw2'),
|
|
47
|
+
];
|
|
48
|
+
// All should be unique
|
|
49
|
+
expect(new Set(ids).size).toBe(3);
|
|
50
|
+
// Requesting same path again should return cached ID
|
|
51
|
+
expect(generator.generateId('1234:5678', '/dev/hidraw1')).toBe(ids[1]);
|
|
52
|
+
});
|
|
53
|
+
test('generates valid hex SHA1 hashes', () => {
|
|
54
|
+
const generator = new StableDeviceIdGenerator();
|
|
55
|
+
const id = generator.generateId('1234:5678', '/dev/hidraw0');
|
|
56
|
+
// Should be 40 character hex string
|
|
57
|
+
expect(id).toMatch(/^[0-9a-f]{40}$/);
|
|
58
|
+
});
|
|
59
|
+
test('deduplicates multiple endpoints of same device', () => {
|
|
60
|
+
const generator = new StableDeviceIdGenerator();
|
|
61
|
+
// Simulate same device with multiple HID endpoints (same path)
|
|
62
|
+
const id1 = generator.generateId('1234:5678', '/dev/hidraw0');
|
|
63
|
+
const id2 = generator.generateId('1234:5678', '/dev/hidraw0');
|
|
64
|
+
const id3 = generator.generateId('1234:5678', '/dev/hidraw0');
|
|
65
|
+
expect(id1).toBe(id2);
|
|
66
|
+
expect(id2).toBe(id3);
|
|
67
|
+
});
|
|
68
|
+
test('handles empty uniqueness key', () => {
|
|
69
|
+
const generator = new StableDeviceIdGenerator();
|
|
70
|
+
const id1 = generator.generateId('', '/dev/hidraw0');
|
|
71
|
+
const id2 = generator.generateId('', '/dev/hidraw1');
|
|
72
|
+
expect(id1).not.toBe(id2);
|
|
73
|
+
expect(id1).toHaveLength(40);
|
|
74
|
+
});
|
|
75
|
+
test('real-world scenario: 2 identical Stream Decks', () => {
|
|
76
|
+
const generator = new StableDeviceIdGenerator();
|
|
77
|
+
// Same vendor:product, different USB paths
|
|
78
|
+
const deck1 = generator.generateId('4057:96', '/dev/hidraw0');
|
|
79
|
+
const deck2 = generator.generateId('4057:96', '/dev/hidraw1');
|
|
80
|
+
expect(deck1).not.toBe(deck2);
|
|
81
|
+
expect(deck1).toHaveLength(40);
|
|
82
|
+
expect(deck2).toHaveLength(40);
|
|
83
|
+
// Re-enumerating same devices should return same IDs
|
|
84
|
+
expect(generator.generateId('4057:96', '/dev/hidraw0')).toBe(deck1);
|
|
85
|
+
expect(generator.generateId('4057:96', '/dev/hidraw1')).toBe(deck2);
|
|
86
|
+
});
|
|
87
|
+
test('pruneNotSeen removes devices not seen in current scan', () => {
|
|
88
|
+
const generator = new StableDeviceIdGenerator();
|
|
89
|
+
// First scan: 3 devices
|
|
90
|
+
const id1 = generator.generateId('1234:5678', '/dev/hidraw0');
|
|
91
|
+
const id2 = generator.generateId('1234:5678', '/dev/hidraw1');
|
|
92
|
+
const id3 = generator.generateId('1234:5678', '/dev/hidraw2');
|
|
93
|
+
generator.pruneNotSeen();
|
|
94
|
+
// Second scan: only 2 devices (hidraw1 disconnected)
|
|
95
|
+
const id1Again = generator.generateId('1234:5678', '/dev/hidraw0');
|
|
96
|
+
const id3Again = generator.generateId('1234:5678', '/dev/hidraw2');
|
|
97
|
+
// IDs should be preserved for devices still present
|
|
98
|
+
expect(id1Again).toBe(id1);
|
|
99
|
+
expect(id3Again).toBe(id3);
|
|
100
|
+
generator.pruneNotSeen();
|
|
101
|
+
// Third scan: hidraw1 reconnects, should get a NEW ID (not cached)
|
|
102
|
+
const id1Third = generator.generateId('1234:5678', '/dev/hidraw0');
|
|
103
|
+
const id2Reconnect = generator.generateId('1234:5678', '/dev/hidraw1');
|
|
104
|
+
const id3Third = generator.generateId('1234:5678', '/dev/hidraw2');
|
|
105
|
+
expect(id1Third).toBe(id1);
|
|
106
|
+
expect(id3Third).toBe(id3);
|
|
107
|
+
// id2Reconnect can reuse the same hash since it was pruned and counter is deterministic
|
|
108
|
+
// It gets index 1 again which produces the same hash as before
|
|
109
|
+
expect(id2Reconnect).toBe(id2);
|
|
110
|
+
});
|
|
111
|
+
test('pruneNotSeen clears scan tracking sets', () => {
|
|
112
|
+
const generator = new StableDeviceIdGenerator();
|
|
113
|
+
// First scan
|
|
114
|
+
const id1 = generator.generateId('1234:5678', '/dev/hidraw0');
|
|
115
|
+
const id2 = generator.generateId('1234:5678', '/dev/hidraw1');
|
|
116
|
+
generator.pruneNotSeen();
|
|
117
|
+
// Second scan - should be able to reuse index 0, 1 etc
|
|
118
|
+
const id3 = generator.generateId('5678:1234', '/dev/hidraw3');
|
|
119
|
+
const id4 = generator.generateId('5678:1234', '/dev/hidraw4');
|
|
120
|
+
// All should be unique
|
|
121
|
+
expect(new Set([id1, id2, id3, id4]).size).toBe(4);
|
|
122
|
+
});
|
|
123
|
+
test('state preserved across multiple scan cycles', () => {
|
|
124
|
+
const generator = new StableDeviceIdGenerator();
|
|
125
|
+
// Scan 1: 3 devices
|
|
126
|
+
const scan1_dev0 = generator.generateId('1234:5678', '/dev/hidraw0');
|
|
127
|
+
const scan1_dev1 = generator.generateId('1234:5678', '/dev/hidraw1');
|
|
128
|
+
const scan1_dev2 = generator.generateId('1234:5678', '/dev/hidraw2');
|
|
129
|
+
generator.pruneNotSeen();
|
|
130
|
+
// Scan 2: same 3 devices
|
|
131
|
+
const scan2_dev0 = generator.generateId('1234:5678', '/dev/hidraw0');
|
|
132
|
+
const scan2_dev1 = generator.generateId('1234:5678', '/dev/hidraw1');
|
|
133
|
+
const scan2_dev2 = generator.generateId('1234:5678', '/dev/hidraw2');
|
|
134
|
+
generator.pruneNotSeen();
|
|
135
|
+
// Scan 3: same 3 devices
|
|
136
|
+
const scan3_dev0 = generator.generateId('1234:5678', '/dev/hidraw0');
|
|
137
|
+
const scan3_dev1 = generator.generateId('1234:5678', '/dev/hidraw1');
|
|
138
|
+
const scan3_dev2 = generator.generateId('1234:5678', '/dev/hidraw2');
|
|
139
|
+
generator.pruneNotSeen();
|
|
140
|
+
// All scans should return identical IDs for same paths
|
|
141
|
+
expect(scan2_dev0).toBe(scan1_dev0);
|
|
142
|
+
expect(scan2_dev1).toBe(scan1_dev1);
|
|
143
|
+
expect(scan2_dev2).toBe(scan1_dev2);
|
|
144
|
+
expect(scan3_dev0).toBe(scan1_dev0);
|
|
145
|
+
expect(scan3_dev1).toBe(scan1_dev1);
|
|
146
|
+
expect(scan3_dev2).toBe(scan1_dev2);
|
|
147
|
+
});
|
|
148
|
+
test('device reconnection at different path reuses counter', () => {
|
|
149
|
+
const generator = new StableDeviceIdGenerator();
|
|
150
|
+
// Scan 1: device at hidraw0
|
|
151
|
+
const id1 = generator.generateId('1234:5678', '/dev/hidraw0');
|
|
152
|
+
generator.pruneNotSeen();
|
|
153
|
+
// Scan 2: device disconnected (not seen)
|
|
154
|
+
generator.pruneNotSeen();
|
|
155
|
+
// Scan 3: same device type reconnects at different path
|
|
156
|
+
const id2 = generator.generateId('1234:5678', '/dev/hidraw5');
|
|
157
|
+
generator.pruneNotSeen();
|
|
158
|
+
// Gets same ID because counter resets and it's index 0 again for this uniqueness key
|
|
159
|
+
expect(id2).toBe(id1);
|
|
160
|
+
// But now if we add another device of same type, it gets different ID
|
|
161
|
+
const id3 = generator.generateId('1234:5678', '/dev/hidraw6');
|
|
162
|
+
expect(id3).not.toBe(id2);
|
|
163
|
+
});
|
|
164
|
+
test('handles partial device changes between scans', () => {
|
|
165
|
+
const generator = new StableDeviceIdGenerator();
|
|
166
|
+
// Scan 1: 4 devices
|
|
167
|
+
const dev0_scan1 = generator.generateId('1234:5678', '/dev/hidraw0');
|
|
168
|
+
const _dev1_scan1 = generator.generateId('1234:5678', '/dev/hidraw1');
|
|
169
|
+
const _dev2_scan1 = generator.generateId('1234:5678', '/dev/hidraw2');
|
|
170
|
+
const dev3_scan1 = generator.generateId('1234:5678', '/dev/hidraw3');
|
|
171
|
+
generator.pruneNotSeen();
|
|
172
|
+
// Scan 2: hidraw1 and hidraw2 removed, hidraw4 added
|
|
173
|
+
const dev0_scan2 = generator.generateId('1234:5678', '/dev/hidraw0');
|
|
174
|
+
const dev3_scan2 = generator.generateId('1234:5678', '/dev/hidraw3');
|
|
175
|
+
const dev4_scan2 = generator.generateId('1234:5678', '/dev/hidraw4');
|
|
176
|
+
generator.pruneNotSeen();
|
|
177
|
+
// Persistent devices keep their IDs
|
|
178
|
+
expect(dev0_scan2).toBe(dev0_scan1);
|
|
179
|
+
expect(dev3_scan2).toBe(dev3_scan1);
|
|
180
|
+
// New device gets next available counter index (reuses counter after reset)
|
|
181
|
+
// After reset, counter 0 goes to dev0, counter 1 goes to dev3, counter 2 goes to dev4
|
|
182
|
+
expect(dev4_scan2).not.toBe(dev0_scan1);
|
|
183
|
+
expect(dev4_scan2).not.toBe(dev3_scan1);
|
|
184
|
+
// All current IDs are unique
|
|
185
|
+
expect(new Set([dev0_scan2, dev3_scan2, dev4_scan2]).size).toBe(3);
|
|
186
|
+
});
|
|
187
|
+
test('multiple device types tracked independently', () => {
|
|
188
|
+
const generator = new StableDeviceIdGenerator();
|
|
189
|
+
// Scan 1: different device types
|
|
190
|
+
const typeA_dev0 = generator.generateId('1111:2222', '/dev/hidraw0');
|
|
191
|
+
const typeB_dev1 = generator.generateId('3333:4444', '/dev/hidraw1');
|
|
192
|
+
const _typeA_dev2 = generator.generateId('1111:2222', '/dev/hidraw2');
|
|
193
|
+
generator.pruneNotSeen();
|
|
194
|
+
// Scan 2: one device of each type removed
|
|
195
|
+
const typeA_dev0_s2 = generator.generateId('1111:2222', '/dev/hidraw0');
|
|
196
|
+
const typeB_dev1_s2 = generator.generateId('3333:4444', '/dev/hidraw1');
|
|
197
|
+
generator.pruneNotSeen();
|
|
198
|
+
// IDs should be preserved
|
|
199
|
+
expect(typeA_dev0_s2).toBe(typeA_dev0);
|
|
200
|
+
expect(typeB_dev1_s2).toBe(typeB_dev1);
|
|
201
|
+
// Scan 3: add another typeA device at new path
|
|
202
|
+
const typeA_dev0_s3 = generator.generateId('1111:2222', '/dev/hidraw0');
|
|
203
|
+
const typeB_dev1_s3 = generator.generateId('3333:4444', '/dev/hidraw1');
|
|
204
|
+
const typeA_dev3_s3 = generator.generateId('1111:2222', '/dev/hidraw3');
|
|
205
|
+
expect(typeA_dev0_s3).toBe(typeA_dev0);
|
|
206
|
+
expect(typeB_dev1_s3).toBe(typeB_dev1);
|
|
207
|
+
// New path for typeA gets next counter index (different from dev0)
|
|
208
|
+
expect(typeA_dev3_s3).not.toBe(typeA_dev0);
|
|
209
|
+
// All current devices have unique IDs
|
|
210
|
+
expect(new Set([typeA_dev0_s3, typeB_dev1_s3, typeA_dev3_s3]).size).toBe(3);
|
|
211
|
+
});
|
|
212
|
+
});
|
|
213
|
+
//# sourceMappingURL=util.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.test.js","sourceRoot":"","sources":["../../src/__tests__/util.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,7 +10,11 @@ export interface HIDDevice {
|
|
|
10
10
|
vendorId: number;
|
|
11
11
|
productId: number;
|
|
12
12
|
path: string;
|
|
13
|
-
|
|
13
|
+
/**
|
|
14
|
+
* The serial number of the device.
|
|
15
|
+
* This is either the serial number provided by the device, or something generated by Companion to give this device a unique ID
|
|
16
|
+
*/
|
|
17
|
+
serialNumber: string;
|
|
14
18
|
manufacturer: string | undefined;
|
|
15
19
|
product: string | undefined;
|
|
16
20
|
release: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/surface-api/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AACrD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AACpD,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,qCAAqC,CAAA;AACxF,OAAO,KAAK,EAAE,aAAa,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAA;AAExE;;;GAGG;AACH,MAAM,WAAW,SAAS;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/surface-api/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AACrD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AACpD,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,qCAAqC,CAAA;AACxF,OAAO,KAAK,EAAE,aAAa,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAA;AAExE;;;GAGG;AACH,MAAM,WAAW,SAAS;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,MAAM,GAAG,SAAS,CAAA;IAChC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;IAC7B,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;CACzB;AAED,MAAM,MAAM,SAAS,GAAG,MAAM,CAAA;AAC9B,MAAM,MAAM,SAAS,GAAG,MAAM,CAAA;AAE9B,MAAM,WAAW,oBAAoB;IACpC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,OAAO,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;CACpB;AACD,MAAM,WAAW,qBAAqB;IACrC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,QAAQ,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACpC;;OAEG;IACH,UAAU,EAAE,OAAO,CAAA;IACnB;;OAEG;IACH,aAAa,EAAE,6BAA6B,CAAA;IAC5C;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,KAAK,CAAC,oBAAoB,GAAG,qBAAqB,CAAC,CAAA;IACvE;;;OAGG;IACH,UAAU,EAAE,iBAAiB,GAAG,IAAI,CAAA;IAEpC;;OAEG;IACH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IAEvB;;OAEG;IACH,YAAY,EAAE,uBAAuB,EAAE,GAAG,IAAI,CAAA;CAC9C;AAED,MAAM,WAAW,iBAAiB;IACjC,OAAO,EAAE,eAAe,CAAA;IACxB,aAAa,EAAE,oBAAoB,CAAA;CACnC;AAED,MAAM,WAAW,gBAAgB;IAChC,SAAS,EAAE,MAAM,CAAA;IAEjB;;OAEG;IACH,KAAK,CAAC,EAAE,UAAU,CAAA;IAElB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IAEd;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,QAAQ;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,2BAA2B;IAC3C,YAAY,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,aAAa,CAAA;CACrB"}
|
package/dist/util.d.ts
CHANGED
|
@@ -5,4 +5,25 @@ export interface RgbColor {
|
|
|
5
5
|
b: number;
|
|
6
6
|
}
|
|
7
7
|
export declare function parseColor(color: string | undefined): RgbColor;
|
|
8
|
+
/**
|
|
9
|
+
* Generator for stable fake serial numbers for usb devices without hardware serials.
|
|
10
|
+
*
|
|
11
|
+
* Generates deterministic serials by hashing just the uniqueness key and an index.
|
|
12
|
+
*/
|
|
13
|
+
export declare class StableDeviceIdGenerator {
|
|
14
|
+
#private;
|
|
15
|
+
/**
|
|
16
|
+
* Generate a stable serial number for a device without a hardware serial.
|
|
17
|
+
*
|
|
18
|
+
* @param uniquenessKey - Identifier for the device type (e.g., "vendorId:productId")
|
|
19
|
+
* @param path - Device path (e.g., "/dev/hidraw0")
|
|
20
|
+
* @returns A stable fake serial number
|
|
21
|
+
*/
|
|
22
|
+
generateId(uniquenessKey: string, devicePath: string): string;
|
|
23
|
+
/**
|
|
24
|
+
* Prune cache entries for devices that were not seen during the current scan.
|
|
25
|
+
* This should be called once after processing all devices in a scan.
|
|
26
|
+
*/
|
|
27
|
+
pruneNotSeen(): void;
|
|
28
|
+
}
|
|
8
29
|
//# sourceMappingURL=util.d.ts.map
|
package/dist/util.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAEA,wBAAgB,WAAW,CAAC,EAAE,EAAE,KAAK,GAAG,IAAI,CAE3C;AAED,MAAM,WAAW,QAAQ;IACxB,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;CACT;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,CAM9D;AAED;;;;GAIG;AACH,qBAAa,uBAAuB;;IAiBnC;;;;;;OAMG;IACH,UAAU,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM;IAqB7D;;;OAGG;IACH,YAAY,IAAI,IAAI;CAiBpB"}
|
package/dist/util.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
1
2
|
export function assertNever(_v) {
|
|
2
3
|
// Nothing to do
|
|
3
4
|
}
|
|
@@ -7,4 +8,69 @@ export function parseColor(color) {
|
|
|
7
8
|
const b = color ? parseInt(color.substr(5, 2), 16) : 0;
|
|
8
9
|
return { r, g, b };
|
|
9
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* Generator for stable fake serial numbers for usb devices without hardware serials.
|
|
13
|
+
*
|
|
14
|
+
* Generates deterministic serials by hashing just the uniqueness key and an index.
|
|
15
|
+
*/
|
|
16
|
+
export class StableDeviceIdGenerator {
|
|
17
|
+
/**
|
|
18
|
+
* Cache of device info to fake serial
|
|
19
|
+
* Map: `${uniquenessKey}||${devicePath}` -> string
|
|
20
|
+
*/
|
|
21
|
+
#previousForDevicePath = new Map();
|
|
22
|
+
/**
|
|
23
|
+
* Track which device paths were seen during the current scan
|
|
24
|
+
* Set of keys: `${uniquenessKey}||${devicePath}`
|
|
25
|
+
*/
|
|
26
|
+
#seenThisScan = new Set();
|
|
27
|
+
/**
|
|
28
|
+
* Track which serialnumbers were returned during this scan
|
|
29
|
+
*/
|
|
30
|
+
#returnedThisScan = new Set();
|
|
31
|
+
/**
|
|
32
|
+
* Generate a stable serial number for a device without a hardware serial.
|
|
33
|
+
*
|
|
34
|
+
* @param uniquenessKey - Identifier for the device type (e.g., "vendorId:productId")
|
|
35
|
+
* @param path - Device path (e.g., "/dev/hidraw0")
|
|
36
|
+
* @returns A stable fake serial number
|
|
37
|
+
*/
|
|
38
|
+
generateId(uniquenessKey, devicePath) {
|
|
39
|
+
const pathCacheKey = `${uniquenessKey}||${devicePath}`;
|
|
40
|
+
// Mark as seen during this scan
|
|
41
|
+
this.#seenThisScan.add(pathCacheKey);
|
|
42
|
+
// If there is something cached against the devicePath, use that
|
|
43
|
+
const cachedSerial = this.#previousForDevicePath.get(pathCacheKey);
|
|
44
|
+
if (cachedSerial)
|
|
45
|
+
return cachedSerial;
|
|
46
|
+
// Loop until we find a non-colliding ID
|
|
47
|
+
for (let i = 0;; i++) {
|
|
48
|
+
const fakeSerial = createHash('sha1').update(`${uniquenessKey}||${i}`).digest('hex');
|
|
49
|
+
if (!this.#returnedThisScan.has(fakeSerial)) {
|
|
50
|
+
this.#returnedThisScan.add(fakeSerial);
|
|
51
|
+
this.#previousForDevicePath.set(pathCacheKey, fakeSerial);
|
|
52
|
+
return fakeSerial;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Prune cache entries for devices that were not seen during the current scan.
|
|
58
|
+
* This should be called once after processing all devices in a scan.
|
|
59
|
+
*/
|
|
60
|
+
pruneNotSeen() {
|
|
61
|
+
// Remove path cache entries that weren't seen
|
|
62
|
+
for (const [key] of this.#previousForDevicePath.entries()) {
|
|
63
|
+
if (!this.#seenThisScan.has(key)) {
|
|
64
|
+
this.#previousForDevicePath.delete(key);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// Clear the seen set for the next scan
|
|
68
|
+
this.#seenThisScan.clear();
|
|
69
|
+
this.#returnedThisScan.clear();
|
|
70
|
+
// Prepopulate the returned set with existing serials to avoid collisions
|
|
71
|
+
for (const serial of this.#previousForDevicePath.values()) {
|
|
72
|
+
this.#returnedThisScan.add(serial);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
10
76
|
//# sourceMappingURL=util.js.map
|
package/dist/util.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,WAAW,CAAC,EAAS;IACpC,gBAAgB;AACjB,CAAC;AAQD,MAAM,UAAU,UAAU,CAAC,KAAyB;IACnD,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACtD,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACtD,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAEtD,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAA;AACnB,CAAC"}
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAExC,MAAM,UAAU,WAAW,CAAC,EAAS;IACpC,gBAAgB;AACjB,CAAC;AAQD,MAAM,UAAU,UAAU,CAAC,KAAyB;IACnD,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACtD,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACtD,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAEtD,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAA;AACnB,CAAC;AAED;;;;GAIG;AACH,MAAM,OAAO,uBAAuB;IACnC;;;OAGG;IACH,sBAAsB,GAAG,IAAI,GAAG,EAAkB,CAAA;IAElD;;;OAGG;IACH,aAAa,GAAG,IAAI,GAAG,EAAU,CAAA;IACjC;;OAEG;IACH,iBAAiB,GAAG,IAAI,GAAG,EAAU,CAAA;IAErC;;;;;;OAMG;IACH,UAAU,CAAC,aAAqB,EAAE,UAAkB;QACnD,MAAM,YAAY,GAAG,GAAG,aAAa,KAAK,UAAU,EAAE,CAAA;QAEtD,gCAAgC;QAChC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;QAEpC,gEAAgE;QAChE,MAAM,YAAY,GAAG,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;QAClE,IAAI,YAAY;YAAE,OAAO,YAAY,CAAA;QAErC,wCAAwC;QACxC,KAAK,IAAI,CAAC,GAAG,CAAC,GAAI,CAAC,EAAE,EAAE,CAAC;YACvB,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,aAAa,KAAK,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;YACpF,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC7C,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;gBACtC,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,YAAY,EAAE,UAAU,CAAC,CAAA;gBACzD,OAAO,UAAU,CAAA;YAClB,CAAC;QACF,CAAC;IACF,CAAC;IAED;;;OAGG;IACH,YAAY;QACX,8CAA8C;QAC9C,KAAK,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,sBAAsB,CAAC,OAAO,EAAE,EAAE,CAAC;YAC3D,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBAClC,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;YACxC,CAAC;QACF,CAAC;QAED,uCAAuC;QACvC,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAA;QAC1B,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,CAAA;QAE9B,yEAAyE;QACzE,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,sBAAsB,CAAC,MAAM,EAAE,EAAE,CAAC;YAC3D,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QACnC,CAAC;IACF,CAAC;CACD"}
|