@companion-surface/base 0.6.1 → 0.7.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.7.0](https://github.com/bitfocus/companion-surface-api/compare/companion-surface-base-v0.6.2...companion-surface-base-v0.7.0) (2025-12-01)
4
+
5
+
6
+ ### Features
7
+
8
+ * surface changePage events ([8653bc1](https://github.com/bitfocus/companion-surface-api/commit/8653bc1e5210cf573bd764c5523d2654fbb75e57))
9
+
10
+ ## [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)
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * rework serialnumber generator to support tracking across runs ([c047e11](https://github.com/bitfocus/companion-surface-api/commit/c047e1139b535e4ecc8d15ff100b4006c5508363))
16
+
3
17
  ## [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)
4
18
 
5
19
 
@@ -21,15 +21,6 @@ describe('StableDeviceIdGenerator', () => {
21
21
  const id2 = generator.generateId('1234:5678', '/dev/hidraw0');
22
22
  expect(id1).toBe(id2);
23
23
  });
24
- test('handles missing device path parameter', () => {
25
- const generator = new StableDeviceIdGenerator();
26
- const id1 = generator.generateId('1234:5678');
27
- const id2 = generator.generateId('1234:5678');
28
- // Without path, each call should generate a new ID
29
- expect(id1).not.toBe(id2);
30
- expect(id1).toHaveLength(40);
31
- expect(id2).toHaveLength(40);
32
- });
33
24
  test('generates stable IDs with counter increment', () => {
34
25
  const generator = new StableDeviceIdGenerator();
35
26
  const id1 = generator.generateId('1234:5678', '/dev/hidraw0');
@@ -59,24 +50,6 @@ describe('StableDeviceIdGenerator', () => {
59
50
  // Requesting same path again should return cached ID
60
51
  expect(generator.generateId('1234:5678', '/dev/hidraw1')).toBe(ids[1]);
61
52
  });
62
- test('handles mixed scenarios with and without device paths', () => {
63
- const generator = new StableDeviceIdGenerator();
64
- const withPath1 = generator.generateId('1234:5678', '/dev/hidraw0');
65
- const withoutPath1 = generator.generateId('1234:5678');
66
- const withPath2 = generator.generateId('1234:5678', '/dev/hidraw1');
67
- const withoutPath2 = generator.generateId('1234:5678');
68
- // All should be unique
69
- expect(new Set([withPath1, withoutPath1, withPath2, withoutPath2]).size).toBe(4);
70
- // Cached path should return same ID
71
- expect(generator.generateId('1234:5678', '/dev/hidraw0')).toBe(withPath1);
72
- });
73
- test('handles undefined device path (same as omitted)', () => {
74
- const generator = new StableDeviceIdGenerator();
75
- const id1 = generator.generateId('1234:5678', undefined);
76
- const id2 = generator.generateId('1234:5678', undefined);
77
- // Should generate different IDs when path is undefined
78
- expect(id1).not.toBe(id2);
79
- });
80
53
  test('generates valid hex SHA1 hashes', () => {
81
54
  const generator = new StableDeviceIdGenerator();
82
55
  const id = generator.generateId('1234:5678', '/dev/hidraw0');
@@ -111,5 +84,130 @@ describe('StableDeviceIdGenerator', () => {
111
84
  expect(generator.generateId('4057:96', '/dev/hidraw0')).toBe(deck1);
112
85
  expect(generator.generateId('4057:96', '/dev/hidraw1')).toBe(deck2);
113
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
+ });
114
212
  });
115
213
  //# sourceMappingURL=util.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"util.test.js","sourceRoot":"","sources":["../../src/__tests__/util.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"util.test.js","sourceRoot":"","sources":["../../src/__tests__/util.test.ts"],"names":[],"mappings":"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"}
@@ -9,6 +9,7 @@ export interface SurfaceContext {
9
9
  keyDownUpById(controlId: string): void;
10
10
  rotateLeftById(controlId: string): void;
11
11
  rotateRightById(controlId: string): void;
12
+ changePage(forward: boolean): void;
12
13
  sendVariableValue(variable: string, value: any): void;
13
14
  }
14
15
  //# sourceMappingURL=context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/surface-api/context.ts"],"names":[],"mappings":"AACA,MAAM,WAAW,gBAAgB;CAGhC;AAED,MAAM,WAAW,cAAc;IAC9B,IAAI,QAAQ,IAAI,OAAO,CAAA;IAEvB,IAAI,YAAY,IAAI,gBAAgB,CAAA;IAEpC,UAAU,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;IAE9B,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACpC,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IAClC,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACtC,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACvC,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IAExC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI,CAAA;CACrD"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/surface-api/context.ts"],"names":[],"mappings":"AACA,MAAM,WAAW,gBAAgB;CAGhC;AAED,MAAM,WAAW,cAAc;IAC9B,IAAI,QAAQ,IAAI,OAAO,CAAA;IAEvB,IAAI,YAAY,IAAI,gBAAgB,CAAA;IAEpC,UAAU,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;IAE9B,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACpC,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IAClC,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACtC,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACvC,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IAExC,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAA;IAElC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI,CAAA;CACrD"}
package/dist/util.d.ts CHANGED
@@ -6,26 +6,24 @@ export interface RgbColor {
6
6
  }
7
7
  export declare function parseColor(color: string | undefined): RgbColor;
8
8
  /**
9
- * Helper class to generate stable, unique device IDs for devices that lack serial numbers.
10
- * Each instance is scoped to a single batch of devices, ensuring uniqueness within that batch.
9
+ * Generator for stable fake serial numbers for usb devices without hardware serials.
11
10
  *
12
- * @example
13
- * ```typescript
14
- * const generator = new StableDeviceIdGenerator()
15
- * const serial1 = generator.generateId('1234:5678', '/dev/hidraw0')
16
- * const serial2 = generator.generateId('1234:5678', '/dev/hidraw1')
17
- * // serial1 and serial2 will be unique even for the same uniquenessKey
18
- * ```
11
+ * Generates deterministic serials by hashing just the uniqueness key and an index.
19
12
  */
20
13
  export declare class StableDeviceIdGenerator {
21
14
  #private;
22
15
  /**
23
- * Generate a stable unique ID for a device within the current batch.
16
+ * Generate a stable serial number for a device without a hardware serial.
24
17
  *
25
- * @param uniquenessKey - A string containing device identifiers (e.g., "vendorId:productId")
26
- * @param devicePath - A unique identifier for the device. Typically the device path. This is to ensure that multiple endpoints of the same hid device get the same id.
27
- * @returns A stable unique identifier for the device
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
28
21
  */
29
- generateId(uniquenessKey: string, devicePath?: string): string;
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;
30
28
  }
31
29
  //# sourceMappingURL=util.d.ts.map
@@ -1 +1 @@
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;;;;;;;;;;;GAWG;AACH,qBAAa,uBAAuB;;IAInC;;;;;;OAMG;IACH,UAAU,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM;CAsB9D"}
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
@@ -9,46 +9,68 @@ export function parseColor(color) {
9
9
  return { r, g, b };
10
10
  }
11
11
  /**
12
- * Helper class to generate stable, unique device IDs for devices that lack serial numbers.
13
- * Each instance is scoped to a single batch of devices, ensuring uniqueness within that batch.
12
+ * Generator for stable fake serial numbers for usb devices without hardware serials.
14
13
  *
15
- * @example
16
- * ```typescript
17
- * const generator = new StableDeviceIdGenerator()
18
- * const serial1 = generator.generateId('1234:5678', '/dev/hidraw0')
19
- * const serial2 = generator.generateId('1234:5678', '/dev/hidraw1')
20
- * // serial1 and serial2 will be unique even for the same uniquenessKey
21
- * ```
14
+ * Generates deterministic serials by hashing just the uniqueness key and an index.
22
15
  */
23
16
  export class StableDeviceIdGenerator {
17
+ /**
18
+ * Cache of device info to fake serial
19
+ * Map: `${uniquenessKey}||${devicePath}` -> string
20
+ */
24
21
  #previousForDevicePath = new Map();
25
- #returnedIds = new Map();
26
22
  /**
27
- * Generate a stable unique ID for a device within the current batch.
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.
28
33
  *
29
- * @param uniquenessKey - A string containing device identifiers (e.g., "vendorId:productId")
30
- * @param devicePath - A unique identifier for the device. Typically the device path. This is to ensure that multiple endpoints of the same hid device get the same id.
31
- * @returns A stable unique identifier for the device
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
32
37
  */
33
38
  generateId(uniquenessKey, devicePath) {
34
- // Generate a complete key
35
- // If there is something cached against the devicePath, use that
36
39
  const pathCacheKey = `${uniquenessKey}||${devicePath}`;
37
- if (devicePath) {
38
- const cached = this.#previousForDevicePath.get(pathCacheKey);
39
- if (cached)
40
- return cached;
41
- }
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;
42
46
  // Loop until we find a non-colliding ID
43
47
  for (let i = 0;; i++) {
44
- const id = `${uniquenessKey}||${i}`;
45
- if (!this.#returnedIds.has(id)) {
46
- const fakeSerial = createHash('sha1').update(id).digest('hex');
47
- this.#returnedIds.set(id, fakeSerial);
48
+ const fakeSerial = createHash('sha1').update(`${uniquenessKey}||${i}`).digest('hex');
49
+ if (!this.#returnedThisScan.has(fakeSerial)) {
50
+ this.#returnedThisScan.add(fakeSerial);
48
51
  this.#previousForDevicePath.set(pathCacheKey, fakeSerial);
49
52
  return fakeSerial;
50
53
  }
51
54
  }
52
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
+ }
53
75
  }
54
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,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;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,uBAAuB;IAC1B,sBAAsB,GAAG,IAAI,GAAG,EAAkB,CAAA;IAClD,YAAY,GAAG,IAAI,GAAG,EAAkB,CAAA;IAEjD;;;;;;OAMG;IACH,UAAU,CAAC,aAAqB,EAAE,UAAmB;QACpD,0BAA0B;QAE1B,gEAAgE;QAChE,MAAM,YAAY,GAAG,GAAG,aAAa,KAAK,UAAU,EAAE,CAAA;QACtD,IAAI,UAAU,EAAE,CAAC;YAChB,MAAM,MAAM,GAAG,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;YAC5D,IAAI,MAAM;gBAAE,OAAO,MAAM,CAAA;QAC1B,CAAC;QAED,wCAAwC;QACxC,KAAK,IAAI,CAAC,GAAG,CAAC,GAAI,CAAC,EAAE,EAAE,CAAC;YACvB,MAAM,EAAE,GAAG,GAAG,aAAa,KAAK,CAAC,EAAE,CAAA;YACnC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;gBAChC,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;gBAE9D,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,EAAE,UAAU,CAAC,CAAA;gBACrC,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,YAAY,EAAE,UAAU,CAAC,CAAA;gBACzD,OAAO,UAAU,CAAA;YAClB,CAAC;QACF,CAAC;IACF,CAAC;CACD"}
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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@companion-surface/base",
3
- "version": "0.6.1",
3
+ "version": "0.7.0",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "repository": "https://github.com/bitfocus/companion-surface-api",