@fcannizzaro/streamdeck-react 0.1.11 → 0.1.12

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.
Files changed (43) hide show
  1. package/dist/action.js +0 -1
  2. package/dist/adapter/index.d.ts +2 -0
  3. package/dist/adapter/physical-device.d.ts +2 -0
  4. package/dist/adapter/physical-device.js +153 -0
  5. package/dist/adapter/types.d.ts +127 -0
  6. package/dist/devtools/bridge.d.ts +2 -2
  7. package/dist/devtools/bridge.js +7 -8
  8. package/dist/devtools/highlight.d.ts +1 -2
  9. package/dist/devtools/highlight.js +4 -3
  10. package/dist/devtools/types.d.ts +5 -5
  11. package/dist/hooks/animation.d.ts +1 -1
  12. package/dist/hooks/animation.js +2 -2
  13. package/dist/hooks/events.js +1 -1
  14. package/dist/hooks/sdk.js +11 -11
  15. package/dist/hooks/utility.js +3 -2
  16. package/dist/index.d.ts +3 -1
  17. package/dist/index.js +2 -1
  18. package/dist/plugin.js +69 -100
  19. package/dist/reconciler/vnode.d.ts +0 -2
  20. package/dist/reconciler/vnode.js +0 -1
  21. package/dist/render/cache.d.ts +5 -17
  22. package/dist/render/cache.js +7 -29
  23. package/dist/render/image-cache.d.ts +8 -7
  24. package/dist/render/image-cache.js +33 -17
  25. package/dist/render/metrics.d.ts +9 -10
  26. package/dist/render/metrics.js +36 -39
  27. package/dist/render/pipeline.d.ts +4 -14
  28. package/dist/render/pipeline.js +47 -111
  29. package/dist/render/png.d.ts +0 -9
  30. package/dist/render/png.js +5 -8
  31. package/dist/render/render-pool.d.ts +0 -2
  32. package/dist/render/render-pool.js +1 -12
  33. package/dist/roots/registry.d.ts +5 -9
  34. package/dist/roots/registry.js +10 -27
  35. package/dist/roots/root.d.ts +7 -34
  36. package/dist/roots/root.js +23 -90
  37. package/dist/roots/touchstrip-root.d.ts +6 -32
  38. package/dist/roots/touchstrip-root.js +61 -181
  39. package/dist/types.d.ts +23 -19
  40. package/package.json +6 -4
  41. package/dist/node_modules/.bun/xxhash-wasm@1.1.0/node_modules/xxhash-wasm/esm/xxhash-wasm.js +0 -3157
  42. package/dist/roots/flush-coordinator.d.ts +0 -18
  43. package/dist/roots/flush-coordinator.js +0 -38
@@ -1,7 +1,6 @@
1
1
  import { shallowEqualSettings } from "./settings-equality.js";
2
2
  import { ReactRoot } from "./root.js";
3
3
  import { TouchStripRoot } from "./touchstrip-root.js";
4
- import { FlushCoordinator } from "./flush-coordinator.js";
5
4
  //#region src/roots/registry.ts
6
5
  var SEGMENT_WIDTH = 200;
7
6
  var KEY_SIZES = {
@@ -79,23 +78,20 @@ function getCanvasInfo(deviceType, surfaceType) {
79
78
  type: "key"
80
79
  };
81
80
  }
82
- var RootRegistry = class RootRegistry {
81
+ var RootRegistry = class {
83
82
  roots = /* @__PURE__ */ new Map();
84
83
  touchStripRoots = /* @__PURE__ */ new Map();
85
84
  touchStripActions = /* @__PURE__ */ new Map();
86
85
  renderConfig;
87
- renderDebounceMs;
88
- sdkInstance;
86
+ adapter;
89
87
  globalSettings = {};
90
88
  onGlobalSettingsChange;
91
89
  wrapper;
92
- flushCoordinator = new FlushCoordinator();
93
90
  /** DevTools observer. Set externally by startDevtoolsServer(). null when devtools is off. */
94
91
  observer = null;
95
- constructor(renderConfig, renderDebounceMs, sdkInstance, onGlobalSettingsChange, wrapper) {
92
+ constructor(renderConfig, adapter, onGlobalSettingsChange, wrapper) {
96
93
  this.renderConfig = renderConfig;
97
- this.renderDebounceMs = renderDebounceMs;
98
- this.sdkInstance = sdkInstance;
94
+ this.adapter = adapter;
99
95
  this.onGlobalSettingsChange = onGlobalSettingsChange;
100
96
  this.wrapper = wrapper;
101
97
  }
@@ -127,13 +123,13 @@ var RootRegistry = class RootRegistry {
127
123
  id: contextId,
128
124
  uuid: definition.uuid,
129
125
  controller,
130
- coordinates: "coordinates" in ev.action ? ev.action.coordinates : void 0,
126
+ coordinates: ev.action.coordinates,
131
127
  isInMultiAction: ev.payload.isInMultiAction
132
128
  };
133
129
  const canvas = getCanvasInfo(device.type, surfaceType);
134
- const root = new ReactRoot(component, actionInfo, deviceInfo, canvas, ev.payload.settings, this.globalSettings, ev.action, this.sdkInstance, this.renderConfig, this.renderDebounceMs, async (settings) => {
130
+ const root = new ReactRoot(component, actionInfo, deviceInfo, canvas, ev.payload.settings, this.globalSettings, ev.action, this.adapter, this.renderConfig, async (settings) => {
135
131
  await ev.action.setSettings(settings);
136
- }, this.onGlobalSettingsChange, this.flushCoordinator, this.wrapper, definition.wrapper, definition.dialLayout);
132
+ }, this.onGlobalSettingsChange, this.wrapper, definition.wrapper, definition.dialLayout);
137
133
  root.eventBus.emitSticky("willAppear", {
138
134
  settings: ev.payload.settings,
139
135
  controller,
@@ -155,9 +151,9 @@ var RootRegistry = class RootRegistry {
155
151
  const actionId = ev.action.id;
156
152
  const device = ev.action.device;
157
153
  const deviceId = device.id;
158
- const column = this.getEncoderColumn(ev);
154
+ const column = ev.action.coordinates?.column;
159
155
  if (column === void 0) {
160
- console.warn("[@fcannizzaro/streamdeck-react] Cannot determine encoder column for touchstrip action:", actionId);
156
+ console.warn("[@fcannizzaro/streamdeck-react] Cannot determine encoder column for TouchStrip action:", actionId);
161
157
  return;
162
158
  }
163
159
  let tbRoot = this.touchStripRoots.get(deviceId);
@@ -168,7 +164,7 @@ var RootRegistry = class RootRegistry {
168
164
  size: device.size,
169
165
  name: device.name
170
166
  };
171
- tbRoot = new TouchStripRoot(definition.touchStrip, deviceInfo, this.globalSettings, this.renderConfig, this.renderDebounceMs, this.onGlobalSettingsChange, this.wrapper, definition.touchStripFPS, this.flushCoordinator);
167
+ tbRoot = new TouchStripRoot(definition.touchStrip, deviceInfo, this.globalSettings, this.renderConfig, this.onGlobalSettingsChange, this.wrapper);
172
168
  this.touchStripRoots.set(deviceId, tbRoot);
173
169
  this.observer?.onTouchStripCreated(deviceId, tbRoot, deviceInfo);
174
170
  }
@@ -176,9 +172,6 @@ var RootRegistry = class RootRegistry {
176
172
  this.observer?.onTouchStripColumnChanged(deviceId, [...tbRoot.columnNumbers], tbRoot.columnActionMap);
177
173
  this.touchStripActions.set(actionId, deviceId);
178
174
  }
179
- getEncoderColumn(ev) {
180
- return ev.action.coordinates?.column;
181
- }
182
175
  destroy(contextId) {
183
176
  const deviceId = this.touchStripActions.get(contextId);
184
177
  if (deviceId) {
@@ -202,18 +195,9 @@ var RootRegistry = class RootRegistry {
202
195
  this.roots.delete(contextId);
203
196
  }
204
197
  }
205
- static INTERACTION_EVENTS = new Set([
206
- "keyDown",
207
- "keyUp",
208
- "dialRotate",
209
- "dialDown",
210
- "dialUp",
211
- "touchTap"
212
- ]);
213
198
  dispatch(contextId, event, payload) {
214
199
  const root = this.roots.get(contextId);
215
200
  if (root) {
216
- if (RootRegistry.INTERACTION_EVENTS.has(event)) root.markInteraction();
217
201
  root.eventBus.emit(event, payload);
218
202
  this.observer?.onDispatch(contextId, event, payload);
219
203
  return;
@@ -222,7 +206,6 @@ var RootRegistry = class RootRegistry {
222
206
  if (deviceId) {
223
207
  const tbRoot = this.touchStripRoots.get(deviceId);
224
208
  if (tbRoot) {
225
- if (RootRegistry.INTERACTION_EVENTS.has(event)) tbRoot.markInteraction();
226
209
  this.dispatchToTouchStrip(tbRoot, contextId, event, payload);
227
210
  this.observer?.onDispatch(contextId, event, payload);
228
211
  }
@@ -2,15 +2,13 @@ import { ComponentType } from 'react';
2
2
  import { VContainer } from '../reconciler/vnode';
3
3
  import { RenderConfig } from '../render/pipeline';
4
4
  import { EventBus } from '../context/event-bus';
5
- import { ActionInfo, CanvasInfo, DeviceInfo, EncoderLayout, StreamDeckAccess, WrapperComponent } from '../types';
6
- import { FlushCoordinator, FlushableRoot } from './flush-coordinator';
5
+ import { ActionInfo, CanvasInfo, DeviceInfo, EncoderLayout, WrapperComponent } from '../types';
7
6
  import { JsonObject } from '@elgato/utils';
8
- import { Action, DialAction, KeyAction } from '@elgato/streamdeck';
9
- export declare class ReactRoot implements FlushableRoot {
7
+ import { AdapterActionHandle, StreamDeckAdapter } from '../adapter/types';
8
+ export declare class ReactRoot {
10
9
  private component;
11
10
  private actionInfo;
12
11
  private deviceInfo;
13
- private flushCoordinator?;
14
12
  private pluginWrapper?;
15
13
  private actionWrapper?;
16
14
  readonly eventBus: EventBus;
@@ -20,27 +18,16 @@ export declare class ReactRoot implements FlushableRoot {
20
18
  private globalSettings;
21
19
  private setSettingsFn;
22
20
  private setGlobalSettingsFn;
23
- private renderDebounceMs;
21
+ private readonly renderDebounceMs;
24
22
  private renderConfig;
25
23
  private canvas;
26
24
  private resolvedDialLayout;
27
- private sdkAction;
28
- private sdkInstance;
25
+ private action;
26
+ private adapter;
29
27
  private disposed;
30
28
  private _renderCount;
31
29
  private _lastRenderReport;
32
30
  private static readonly RENDER_WARN_THRESHOLD;
33
- private _rendering;
34
- private _pendingFlush;
35
- private _recentRenders;
36
- private _lastInteraction;
37
- private static readonly ANIMATION_WINDOW_MS;
38
- private static readonly ANIMATION_THRESHOLD;
39
- private static readonly INTERACTION_COOLDOWN_MS;
40
- private static readonly IDLE_THRESHOLD_MS;
41
- private _lastFlushTime;
42
- /** Current render priority (lower = higher priority). Used by flush coordinator for ordering. */
43
- get priority(): number;
44
31
  /** Last data URI successfully sent to hardware. Used by devtools snapshots. */
45
32
  lastDataUri: string | null;
46
33
  /**
@@ -57,25 +44,11 @@ export declare class ReactRoot implements FlushableRoot {
57
44
  private streamDeckValue;
58
45
  private settingsValue;
59
46
  private globalSettingsValue;
60
- constructor(component: ComponentType, actionInfo: ActionInfo, deviceInfo: DeviceInfo, canvas: CanvasInfo, initialSettings: JsonObject, initialGlobalSettings: JsonObject, sdkAction: Action | DialAction | KeyAction, sdkInstance: StreamDeckAccess["sdk"], renderConfig: RenderConfig, renderDebounceMs: number, onSettingsChange: (settings: JsonObject) => Promise<void>, onGlobalSettingsChange: (settings: JsonObject) => Promise<void>, flushCoordinator?: FlushCoordinator | undefined, pluginWrapper?: WrapperComponent | undefined, actionWrapper?: WrapperComponent | undefined, dialLayout?: EncoderLayout);
47
+ constructor(component: ComponentType, actionInfo: ActionInfo, deviceInfo: DeviceInfo, canvas: CanvasInfo, initialSettings: JsonObject, initialGlobalSettings: JsonObject, action: AdapterActionHandle, adapter: StreamDeckAdapter, renderConfig: RenderConfig, onSettingsChange: (settings: JsonObject) => Promise<void>, onGlobalSettingsChange: (settings: JsonObject) => Promise<void>, pluginWrapper?: WrapperComponent | undefined, actionWrapper?: WrapperComponent | undefined, dialLayout?: EncoderLayout);
61
48
  private render;
62
49
  private buildTree;
63
50
  private scheduleRerender;
64
- /** Record a user interaction (keyDown, dialRotate, etc.) for adaptive debounce. */
65
- markInteraction(): void;
66
- /** Compute effective debounce based on recent render frequency and interaction state. */
67
- private get effectiveDebounceMs();
68
51
  private flush;
69
- /**
70
- * Submit this root for flushing. Routes through the coordinator
71
- * (priority-ordered) when available, or flushes directly.
72
- */
73
- private submitFlush;
74
- /**
75
- * Execute the flush. Called by FlushCoordinator in priority order,
76
- * or directly when no coordinator is present.
77
- */
78
- executeFlush(): Promise<void>;
79
52
  private doFlush;
80
53
  updateSettings(settings: JsonObject): void;
81
54
  updateGlobalSettings(settings: JsonObject): void;
@@ -1,4 +1,4 @@
1
- import { createVContainer } from "../reconciler/vnode.js";
1
+ import { clearDirtyFlags, createVContainer } from "../reconciler/vnode.js";
2
2
  import { reconciler } from "../reconciler/renderer.js";
3
3
  import { renderToDataUri } from "../render/pipeline.js";
4
4
  import { EventBus } from "../context/event-bus.js";
@@ -27,35 +27,16 @@ var ReactRoot = class ReactRoot {
27
27
  globalSettings;
28
28
  setSettingsFn;
29
29
  setGlobalSettingsFn;
30
- renderDebounceMs;
30
+ renderDebounceMs = 17;
31
31
  renderConfig;
32
32
  canvas;
33
33
  resolvedDialLayout;
34
- sdkAction;
35
- sdkInstance;
34
+ action;
35
+ adapter;
36
36
  disposed = false;
37
37
  _renderCount = 0;
38
38
  _lastRenderReport = 0;
39
39
  static RENDER_WARN_THRESHOLD = 30;
40
- _rendering = false;
41
- _pendingFlush = false;
42
- _recentRenders = [];
43
- _lastInteraction = 0;
44
- static ANIMATION_WINDOW_MS = 100;
45
- static ANIMATION_THRESHOLD = 2;
46
- static INTERACTION_COOLDOWN_MS = 500;
47
- static IDLE_THRESHOLD_MS = 2e3;
48
- _lastFlushTime = 0;
49
- /** Current render priority (lower = higher priority). Used by flush coordinator for ordering. */
50
- get priority() {
51
- const now = Date.now();
52
- const cutoff = now - ReactRoot.ANIMATION_WINDOW_MS;
53
- while (this._recentRenders.length > 0 && this._recentRenders[0] < cutoff) this._recentRenders.shift();
54
- if (this._recentRenders.length > ReactRoot.ANIMATION_THRESHOLD) return 0;
55
- if (now - this._lastInteraction < ReactRoot.INTERACTION_COOLDOWN_MS) return 1;
56
- if (this._lastFlushTime > 0 && now - this._lastFlushTime > ReactRoot.IDLE_THRESHOLD_MS) return 3;
57
- return 2;
58
- }
59
40
  /** Last data URI successfully sent to hardware. Used by devtools snapshots. */
60
41
  lastDataUri = null;
61
42
  /**
@@ -68,16 +49,12 @@ var ReactRoot = class ReactRoot {
68
49
  /** Push an arbitrary data URI to the hardware. Used by devtools highlight overlay. */
69
50
  async pushImage(dataUri) {
70
51
  if (this.disposed) return;
71
- if (this.canvas.type === "key") {
72
- if ("setImage" in this.sdkAction) await this.sdkAction.setImage(dataUri);
73
- } else if (this.canvas.type === "dial") {
74
- if ("setFeedback" in this.sdkAction) await this.sdkAction.setFeedback({
75
- canvas: dataUri,
76
- title: ""
77
- });
78
- } else if (this.canvas.type === "touch") {
79
- if ("setFeedback" in this.sdkAction) await this.sdkAction.setFeedback({ canvas: dataUri });
80
- }
52
+ if (this.canvas.type === "key") await this.action.setImage(dataUri);
53
+ else if (this.canvas.type === "dial") await this.action.setFeedback({
54
+ canvas: dataUri,
55
+ title: ""
56
+ });
57
+ else if (this.canvas.type === "touch") await this.action.setFeedback({ canvas: dataUri });
81
58
  }
82
59
  /** Exposes the VContainer for devtools inspection. */
83
60
  get vcontainer() {
@@ -86,20 +63,18 @@ var ReactRoot = class ReactRoot {
86
63
  streamDeckValue;
87
64
  settingsValue;
88
65
  globalSettingsValue;
89
- constructor(component, actionInfo, deviceInfo, canvas, initialSettings, initialGlobalSettings, sdkAction, sdkInstance, renderConfig, renderDebounceMs, onSettingsChange, onGlobalSettingsChange, flushCoordinator, pluginWrapper, actionWrapper, dialLayout) {
66
+ constructor(component, actionInfo, deviceInfo, canvas, initialSettings, initialGlobalSettings, action, adapter, renderConfig, onSettingsChange, onGlobalSettingsChange, pluginWrapper, actionWrapper, dialLayout) {
90
67
  this.component = component;
91
68
  this.actionInfo = actionInfo;
92
69
  this.deviceInfo = deviceInfo;
93
- this.flushCoordinator = flushCoordinator;
94
70
  this.pluginWrapper = pluginWrapper;
95
71
  this.actionWrapper = actionWrapper;
96
72
  this.canvas = canvas;
97
73
  this.settings = { ...initialSettings };
98
74
  this.globalSettings = { ...initialGlobalSettings };
99
- this.sdkAction = sdkAction;
100
- this.sdkInstance = sdkInstance;
75
+ this.action = action;
76
+ this.adapter = adapter;
101
77
  this.renderConfig = renderConfig;
102
- this.renderDebounceMs = renderDebounceMs;
103
78
  this.resolvedDialLayout = resolveDialLayout(dialLayout);
104
79
  this.setSettingsFn = (partial) => {
105
80
  const hasChanges = partialHasChanges(this.settings, partial);
@@ -132,8 +107,8 @@ var ReactRoot = class ReactRoot {
132
107
  this.scheduleRerender();
133
108
  };
134
109
  this.streamDeckValue = {
135
- action: this.sdkAction,
136
- sdk: this.sdkInstance
110
+ action: this.action,
111
+ adapter: this.adapter
137
112
  };
138
113
  this.settingsValue = {
139
114
  settings: this.settings,
@@ -154,7 +129,8 @@ var ReactRoot = class ReactRoot {
154
129
  console.error("[@fcannizzaro/streamdeck-react] Recoverable error:", err);
155
130
  }, () => {});
156
131
  if (canvas.type === "dial" || canvas.type === "touch") {
157
- if ("setFeedbackLayout" in this.sdkAction) this.sdkAction.setFeedbackLayout(this.resolvedDialLayout);
132
+ const layout = this.resolvedDialLayout;
133
+ this.action.setFeedbackLayout(typeof layout === "string" ? layout : layout);
158
134
  }
159
135
  this.eventBus.ownerId = actionInfo.id;
160
136
  this.eventBus.ownerUuid = actionInfo.uuid;
@@ -174,55 +150,17 @@ var ReactRoot = class ReactRoot {
174
150
  if (this.disposed) return;
175
151
  this.render();
176
152
  }
177
- /** Record a user interaction (keyDown, dialRotate, etc.) for adaptive debounce. */
178
- markInteraction() {
179
- this._lastInteraction = Date.now();
180
- }
181
- /** Compute effective debounce based on recent render frequency and interaction state. */
182
- get effectiveDebounceMs() {
183
- const now = Date.now();
184
- const cutoff = now - ReactRoot.ANIMATION_WINDOW_MS;
185
- while (this._recentRenders.length > 0 && this._recentRenders[0] < cutoff) this._recentRenders.shift();
186
- if (this._recentRenders.length > ReactRoot.ANIMATION_THRESHOLD) return 0;
187
- if (now - this._lastInteraction < ReactRoot.INTERACTION_COOLDOWN_MS) return Math.min(this.renderDebounceMs, 16);
188
- return this.renderDebounceMs;
189
- }
190
153
  async flush() {
191
154
  if (this.disposed) return;
192
- if (this._rendering) {
193
- this._pendingFlush = true;
194
- return;
195
- }
196
- this._recentRenders.push(Date.now());
197
- const debounce = this.effectiveDebounceMs;
198
- if (debounce > 0 && this.container.renderTimer !== null) clearTimeout(this.container.renderTimer);
199
- if (debounce > 0) this.container.renderTimer = setTimeout(() => {
155
+ if (this.renderDebounceMs > 0 && this.container.renderTimer !== null) clearTimeout(this.container.renderTimer);
156
+ if (this.renderDebounceMs > 0) this.container.renderTimer = setTimeout(async () => {
200
157
  this.container.renderTimer = null;
201
- this.submitFlush();
202
- }, debounce);
203
- else this.submitFlush();
204
- }
205
- /**
206
- * Submit this root for flushing. Routes through the coordinator
207
- * (priority-ordered) when available, or flushes directly.
208
- */
209
- submitFlush() {
210
- if (this.disposed) return;
211
- if (this.flushCoordinator) this.flushCoordinator.requestFlush(this);
212
- else this.doFlush();
213
- }
214
- /**
215
- * Execute the flush. Called by FlushCoordinator in priority order,
216
- * or directly when no coordinator is present.
217
- */
218
- async executeFlush() {
219
- await this.doFlush();
158
+ await this.doFlush();
159
+ }, this.renderDebounceMs);
160
+ else await this.doFlush();
220
161
  }
221
162
  async doFlush() {
222
163
  if (this.disposed) return;
223
- this._rendering = true;
224
- this._pendingFlush = false;
225
- this._lastFlushTime = Date.now();
226
164
  if (this.renderConfig.debug) {
227
165
  this._renderCount++;
228
166
  const now = Date.now();
@@ -234,6 +172,7 @@ var ReactRoot = class ReactRoot {
234
172
  }
235
173
  try {
236
174
  const dataUri = await renderToDataUri(this.container, this.canvas.width, this.canvas.height, this.renderConfig);
175
+ clearDirtyFlags(this.container);
237
176
  if (dataUri === null || this.disposed) return;
238
177
  this.lastDataUri = dataUri;
239
178
  if (!this.suppressHardwarePush) this.pushImage(dataUri).catch((err) => {
@@ -241,12 +180,6 @@ var ReactRoot = class ReactRoot {
241
180
  });
242
181
  } catch (err) {
243
182
  console.error("[@fcannizzaro/streamdeck-react] Render error:", err);
244
- } finally {
245
- this._rendering = false;
246
- if (this._pendingFlush && !this.disposed) {
247
- this._pendingFlush = false;
248
- await this.doFlush();
249
- }
250
183
  }
251
184
  }
252
185
  updateSettings(settings) {
@@ -3,38 +3,25 @@ import { VContainer } from '../reconciler/vnode';
3
3
  import { RenderConfig } from '../render/pipeline';
4
4
  import { EventBus } from '../context/event-bus';
5
5
  import { DeviceInfo, WrapperComponent } from '../types';
6
- import { FlushCoordinator, FlushableRoot } from './flush-coordinator';
7
- import { DialAction } from '@elgato/streamdeck';
6
+ import { AdapterActionHandle } from '../adapter/types';
8
7
  import { JsonObject } from '@elgato/utils';
9
- export declare class TouchStripRoot implements FlushableRoot {
8
+ export declare class TouchStripRoot {
10
9
  private component;
11
- private flushCoordinator?;
12
10
  readonly eventBus: EventBus;
13
11
  private container;
14
12
  private fiberRoot;
15
13
  private columns;
16
14
  private globalSettings;
17
15
  private setGlobalSettingsFn;
18
- private renderDebounceMs;
19
16
  private renderConfig;
20
17
  private deviceInfo;
21
18
  private disposed;
22
- private fps;
23
19
  private pluginWrapper?;
20
+ private readonly renderDebounceMs;
24
21
  private _renderCount;
25
22
  private _lastRenderReport;
26
23
  private static readonly RENDER_WARN_THRESHOLD;
27
- private _rendering;
28
- private _pendingFlush;
29
- private _recentRenders;
30
- private _lastInteraction;
31
- private static readonly ANIMATION_WINDOW_MS;
32
- private static readonly ANIMATION_THRESHOLD;
33
- private static readonly INTERACTION_COOLDOWN_MS;
34
- private static readonly IDLE_THRESHOLD_MS;
35
- private _lastFlushTime;
36
- /** Current render priority (lower = higher priority). Used by flush coordinator. */
37
- get priority(): number;
24
+ private _lastSegmentUriHash;
38
25
  /** Last rendered per-column data URIs. Used by devtools snapshots. */
39
26
  lastSegmentUris: Map<number, string>;
40
27
  /**
@@ -64,8 +51,8 @@ export declare class TouchStripRoot implements FlushableRoot {
64
51
  get columnActionMap(): Map<number, string>;
65
52
  private globalSettingsValue;
66
53
  private touchStripValue;
67
- constructor(component: ComponentType, deviceInfo: DeviceInfo, initialGlobalSettings: JsonObject, renderConfig: RenderConfig, renderDebounceMs: number, onGlobalSettingsChange: (settings: JsonObject) => Promise<void>, pluginWrapper?: WrapperComponent, touchStripFPS?: number, flushCoordinator?: FlushCoordinator | undefined);
68
- addColumn(column: number, actionId: string, sdkAction: DialAction): void;
54
+ constructor(component: ComponentType, deviceInfo: DeviceInfo, initialGlobalSettings: JsonObject, renderConfig: RenderConfig, onGlobalSettingsChange: (settings: JsonObject) => Promise<void>, pluginWrapper?: WrapperComponent);
55
+ addColumn(column: number, actionId: string, sdkAction: AdapterActionHandle): void;
69
56
  removeColumn(column: number): void;
70
57
  get isEmpty(): boolean;
71
58
  findColumnByActionId(actionId: string): number | undefined;
@@ -73,20 +60,7 @@ export declare class TouchStripRoot implements FlushableRoot {
73
60
  private render;
74
61
  private buildTree;
75
62
  private scheduleRerender;
76
- /** Record a user interaction for adaptive debounce. */
77
- markInteraction(): void;
78
- private get effectiveDebounceMs();
79
63
  private flush;
80
- /**
81
- * Submit this root for flushing. Routes through the coordinator
82
- * (priority-ordered) when available, or flushes directly.
83
- */
84
- private submitFlush;
85
- /**
86
- * Execute the flush. Called by FlushCoordinator in priority order,
87
- * or directly when no coordinator is present.
88
- */
89
- executeFlush(): Promise<void>;
90
64
  private doFlush;
91
65
  updateGlobalSettings(settings: JsonObject): void;
92
66
  unmount(): void;