@fcannizzaro/streamdeck-react 0.1.9 → 0.1.11

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 (74) hide show
  1. package/LICENSE +190 -21
  2. package/README.md +3 -1
  3. package/dist/action.d.ts +2 -2
  4. package/dist/action.js +2 -2
  5. package/dist/bundler-shared.d.ts +11 -0
  6. package/dist/bundler-shared.js +11 -0
  7. package/dist/context/event-bus.d.ts +1 -1
  8. package/dist/context/event-bus.js +1 -1
  9. package/dist/context/touchstrip-context.d.ts +2 -0
  10. package/dist/context/touchstrip-context.js +5 -0
  11. package/dist/devtools/bridge.d.ts +35 -7
  12. package/dist/devtools/bridge.js +153 -46
  13. package/dist/devtools/highlight.d.ts +6 -0
  14. package/dist/devtools/highlight.js +106 -57
  15. package/dist/devtools/index.js +6 -0
  16. package/dist/devtools/observers/lifecycle.d.ts +4 -4
  17. package/dist/devtools/server.d.ts +6 -1
  18. package/dist/devtools/server.js +6 -1
  19. package/dist/devtools/types.d.ts +50 -6
  20. package/dist/font-inline.d.ts +5 -1
  21. package/dist/font-inline.js +8 -3
  22. package/dist/hooks/animation.d.ts +154 -0
  23. package/dist/hooks/animation.js +381 -0
  24. package/dist/hooks/events.js +1 -5
  25. package/dist/hooks/touchstrip.d.ts +6 -0
  26. package/dist/hooks/touchstrip.js +37 -0
  27. package/dist/index.d.ts +7 -2
  28. package/dist/index.js +3 -2
  29. package/dist/manifest-codegen.d.ts +38 -0
  30. package/dist/manifest-codegen.js +110 -0
  31. package/dist/node_modules/.bun/xxhash-wasm@1.1.0/node_modules/xxhash-wasm/esm/xxhash-wasm.js +3157 -0
  32. package/dist/plugin.js +20 -9
  33. package/dist/reconciler/host-config.js +19 -1
  34. package/dist/reconciler/vnode.d.ts +26 -0
  35. package/dist/reconciler/vnode.js +41 -10
  36. package/dist/render/buffer-pool.d.ts +19 -0
  37. package/dist/render/buffer-pool.js +51 -0
  38. package/dist/render/cache.d.ts +41 -0
  39. package/dist/render/cache.js +159 -5
  40. package/dist/render/image-cache.d.ts +53 -0
  41. package/dist/render/image-cache.js +128 -0
  42. package/dist/render/metrics.d.ts +58 -0
  43. package/dist/render/metrics.js +101 -0
  44. package/dist/render/pipeline.d.ts +46 -1
  45. package/dist/render/pipeline.js +370 -36
  46. package/dist/render/png.d.ts +10 -1
  47. package/dist/render/png.js +31 -13
  48. package/dist/render/render-pool.d.ts +26 -0
  49. package/dist/render/render-pool.js +141 -0
  50. package/dist/render/svg.d.ts +7 -0
  51. package/dist/render/svg.js +139 -0
  52. package/dist/render/worker.d.ts +1 -0
  53. package/dist/rollup.d.ts +23 -9
  54. package/dist/rollup.js +24 -9
  55. package/dist/roots/flush-coordinator.d.ts +18 -0
  56. package/dist/roots/flush-coordinator.js +38 -0
  57. package/dist/roots/registry.d.ts +6 -4
  58. package/dist/roots/registry.js +47 -33
  59. package/dist/roots/root.d.ts +32 -2
  60. package/dist/roots/root.js +104 -14
  61. package/dist/roots/settings-equality.d.ts +5 -0
  62. package/dist/roots/settings-equality.js +24 -0
  63. package/dist/roots/touchstrip-root.d.ts +93 -0
  64. package/dist/roots/touchstrip-root.js +383 -0
  65. package/dist/types.d.ts +62 -16
  66. package/dist/vite.d.ts +22 -8
  67. package/dist/vite.js +24 -8
  68. package/package.json +5 -4
  69. package/dist/context/touchbar-context.d.ts +0 -2
  70. package/dist/context/touchbar-context.js +0 -5
  71. package/dist/hooks/touchbar.d.ts +0 -6
  72. package/dist/hooks/touchbar.js +0 -37
  73. package/dist/roots/touchbar-root.d.ts +0 -45
  74. package/dist/roots/touchbar-root.js +0 -175
@@ -1,37 +0,0 @@
1
- import { EventBusContext } from "../context/providers.js";
2
- import { TouchBarContext } from "../context/touchbar-context.js";
3
- import { useCallbackRef } from "./internal/useCallbackRef.js";
4
- import { useContext, useEffect } from "react";
5
- //#region src/hooks/touchbar.ts
6
- function useTouchBarEvent(event, callback) {
7
- const bus = useContext(EventBusContext);
8
- const callbackRef = useCallbackRef(callback);
9
- useEffect(() => {
10
- const handler = (payload) => {
11
- callbackRef.current(payload);
12
- };
13
- bus.on(event, handler);
14
- return () => bus.off(event, handler);
15
- }, [
16
- bus,
17
- callbackRef,
18
- event
19
- ]);
20
- }
21
- function useTouchBar() {
22
- return useContext(TouchBarContext);
23
- }
24
- function useTouchBarTap(callback) {
25
- useTouchBarEvent("touchBarTap", callback);
26
- }
27
- function useTouchBarDialRotate(callback) {
28
- useTouchBarEvent("touchBarDialRotate", callback);
29
- }
30
- function useTouchBarDialDown(callback) {
31
- useTouchBarEvent("touchBarDialDown", callback);
32
- }
33
- function useTouchBarDialUp(callback) {
34
- useTouchBarEvent("touchBarDialUp", callback);
35
- }
36
- //#endregion
37
- export { useTouchBar, useTouchBarDialDown, useTouchBarDialRotate, useTouchBarDialUp, useTouchBarTap };
@@ -1,45 +0,0 @@
1
- import { ComponentType } from 'react';
2
- import { VContainer } from '../reconciler/vnode';
3
- import { RenderConfig } from '../render/pipeline';
4
- import { EventBus } from '../context/event-bus';
5
- import { DeviceInfo, WrapperComponent } from '../types';
6
- import { DialAction } from '@elgato/streamdeck';
7
- import { JsonObject } from '@elgato/utils';
8
- export declare class TouchBarRoot {
9
- private component;
10
- readonly eventBus: EventBus;
11
- private container;
12
- private fiberRoot;
13
- private columns;
14
- private globalSettings;
15
- private setGlobalSettingsFn;
16
- private renderDebounceMs;
17
- private renderConfig;
18
- private deviceInfo;
19
- private disposed;
20
- private fps;
21
- private pluginWrapper?;
22
- /** Last rendered per-column data URIs. Used by devtools snapshots. */
23
- lastSegmentUris: Map<number, string>;
24
- /** Exposes the VContainer for devtools inspection. */
25
- get vcontainer(): VContainer;
26
- /** Sorted column numbers for devtools observer. */
27
- get columnNumbers(): number[];
28
- /** Column → actionId map for devtools observer. */
29
- get columnActionMap(): Map<number, string>;
30
- private globalSettingsValue;
31
- private touchBarValue;
32
- constructor(component: ComponentType, deviceInfo: DeviceInfo, initialGlobalSettings: JsonObject, renderConfig: RenderConfig, renderDebounceMs: number, onGlobalSettingsChange: (settings: JsonObject) => Promise<void>, pluginWrapper?: WrapperComponent, touchBarFPS?: number);
33
- addColumn(column: number, actionId: string, sdkAction: DialAction): void;
34
- removeColumn(column: number): void;
35
- get isEmpty(): boolean;
36
- findColumnByActionId(actionId: string): number | undefined;
37
- private updateTouchBarInfo;
38
- private render;
39
- private buildTree;
40
- private scheduleRerender;
41
- private flush;
42
- private doFlush;
43
- updateGlobalSettings(settings: JsonObject): void;
44
- unmount(): void;
45
- }
@@ -1,175 +0,0 @@
1
- import { createVContainer } from "../reconciler/vnode.js";
2
- import { reconciler } from "../reconciler/renderer.js";
3
- import { renderToRaw, sliceToDataUri } from "../render/pipeline.js";
4
- import { EventBus } from "../context/event-bus.js";
5
- import { DeviceContext, EventBusContext, GlobalSettingsContext } from "../context/providers.js";
6
- import { TouchBarContext } from "../context/touchbar-context.js";
7
- import { createElement } from "react";
8
- //#region src/roots/touchbar-root.ts
9
- var SEGMENT_WIDTH = 200;
10
- var SEGMENT_HEIGHT = 100;
11
- var DEFAULT_TOUCHBAR_FPS = 60;
12
- var TouchBarRoot = class {
13
- eventBus = new EventBus();
14
- container;
15
- fiberRoot;
16
- columns = /* @__PURE__ */ new Map();
17
- globalSettings;
18
- setGlobalSettingsFn;
19
- renderDebounceMs;
20
- renderConfig;
21
- deviceInfo;
22
- disposed = false;
23
- fps;
24
- pluginWrapper;
25
- /** Last rendered per-column data URIs. Used by devtools snapshots. */
26
- lastSegmentUris = /* @__PURE__ */ new Map();
27
- /** Exposes the VContainer for devtools inspection. */
28
- get vcontainer() {
29
- return this.container;
30
- }
31
- /** Sorted column numbers for devtools observer. */
32
- get columnNumbers() {
33
- return [...this.columns.keys()].sort((a, b) => a - b);
34
- }
35
- /** Column → actionId map for devtools observer. */
36
- get columnActionMap() {
37
- const map = /* @__PURE__ */ new Map();
38
- for (const [col, entry] of this.columns) map.set(col, entry.actionId);
39
- return map;
40
- }
41
- globalSettingsValue;
42
- touchBarValue;
43
- constructor(component, deviceInfo, initialGlobalSettings, renderConfig, renderDebounceMs, onGlobalSettingsChange, pluginWrapper, touchBarFPS) {
44
- this.component = component;
45
- this.deviceInfo = deviceInfo;
46
- this.globalSettings = { ...initialGlobalSettings };
47
- this.renderConfig = renderConfig;
48
- this.fps = touchBarFPS ?? DEFAULT_TOUCHBAR_FPS;
49
- this.renderDebounceMs = touchBarFPS != null ? Math.max(1, Math.round(1e3 / touchBarFPS)) : renderDebounceMs;
50
- this.pluginWrapper = pluginWrapper;
51
- this.setGlobalSettingsFn = (partial) => {
52
- this.globalSettings = {
53
- ...this.globalSettings,
54
- ...partial
55
- };
56
- this.globalSettingsValue = {
57
- settings: this.globalSettings,
58
- setSettings: this.setGlobalSettingsFn
59
- };
60
- onGlobalSettingsChange(this.globalSettings);
61
- this.scheduleRerender();
62
- };
63
- this.globalSettingsValue = {
64
- settings: this.globalSettings,
65
- setSettings: this.setGlobalSettingsFn
66
- };
67
- this.touchBarValue = {
68
- width: 0,
69
- height: SEGMENT_HEIGHT,
70
- columns: [],
71
- segmentWidth: SEGMENT_WIDTH,
72
- fps: this.fps
73
- };
74
- this.container = createVContainer(() => {
75
- this.flush();
76
- });
77
- this.fiberRoot = reconciler.createContainer(this.container, 0, null, false, null, "", (err) => {
78
- console.error("[@fcannizzaro/streamdeck-react] TouchBar uncaught error:", err);
79
- }, (err) => {
80
- console.error("[@fcannizzaro/streamdeck-react] TouchBar caught error:", err);
81
- }, (err) => {
82
- console.error("[@fcannizzaro/streamdeck-react] TouchBar recoverable error:", err);
83
- }, () => {});
84
- this.eventBus.ownerId = `touchbar:${deviceInfo.id}`;
85
- }
86
- addColumn(column, actionId, sdkAction) {
87
- this.columns.set(column, {
88
- actionId,
89
- sdkAction
90
- });
91
- this.updateTouchBarInfo();
92
- this.scheduleRerender();
93
- }
94
- removeColumn(column) {
95
- this.columns.delete(column);
96
- if (this.columns.size === 0) return;
97
- this.updateTouchBarInfo();
98
- this.scheduleRerender();
99
- }
100
- get isEmpty() {
101
- return this.columns.size === 0;
102
- }
103
- findColumnByActionId(actionId) {
104
- for (const [column, entry] of this.columns) if (entry.actionId === actionId) return column;
105
- }
106
- updateTouchBarInfo() {
107
- const sortedColumns = [...this.columns.keys()].sort((a, b) => a - b);
108
- this.touchBarValue = {
109
- width: (sortedColumns.length > 0 ? sortedColumns[sortedColumns.length - 1] + 1 : 0) * SEGMENT_WIDTH,
110
- height: SEGMENT_HEIGHT,
111
- columns: sortedColumns,
112
- segmentWidth: SEGMENT_WIDTH,
113
- fps: this.fps
114
- };
115
- }
116
- render() {
117
- if (this.disposed) return;
118
- const element = this.buildTree();
119
- reconciler.updateContainer(element, this.fiberRoot, null, () => {});
120
- }
121
- buildTree() {
122
- let child = createElement(this.component);
123
- if (this.pluginWrapper) child = createElement(this.pluginWrapper, null, child);
124
- return createElement(TouchBarContext.Provider, { value: this.touchBarValue }, createElement(DeviceContext.Provider, { value: this.deviceInfo }, createElement(EventBusContext.Provider, { value: this.eventBus }, createElement(GlobalSettingsContext.Provider, { value: this.globalSettingsValue }, child))));
125
- }
126
- scheduleRerender() {
127
- if (this.disposed) return;
128
- this.render();
129
- }
130
- async flush() {
131
- if (this.disposed) return;
132
- if (this.renderDebounceMs > 0 && this.container.renderTimer !== null) clearTimeout(this.container.renderTimer);
133
- if (this.renderDebounceMs > 0) this.container.renderTimer = setTimeout(async () => {
134
- this.container.renderTimer = null;
135
- await this.doFlush();
136
- }, this.renderDebounceMs);
137
- else await this.doFlush();
138
- }
139
- async doFlush() {
140
- if (this.disposed || this.columns.size === 0) return;
141
- try {
142
- const width = this.touchBarValue.width;
143
- if (width === 0) return;
144
- const result = await renderToRaw(this.container, width, SEGMENT_HEIGHT, this.renderConfig);
145
- if (result === null || this.disposed) return;
146
- const feedbackPromises = [];
147
- for (const [column, entry] of this.columns) {
148
- const sliceUri = sliceToDataUri(result.buffer, result.width, result.height, column, SEGMENT_WIDTH, SEGMENT_HEIGHT);
149
- this.lastSegmentUris.set(column, sliceUri);
150
- feedbackPromises.push(entry.sdkAction.setFeedback({ canvas: sliceUri }));
151
- }
152
- await Promise.all(feedbackPromises);
153
- } catch (err) {
154
- console.error("[@fcannizzaro/streamdeck-react] TouchBar render error:", err);
155
- }
156
- }
157
- updateGlobalSettings(settings) {
158
- this.globalSettings = { ...settings };
159
- this.globalSettingsValue = {
160
- settings: this.globalSettings,
161
- setSettings: this.setGlobalSettingsFn
162
- };
163
- this.scheduleRerender();
164
- }
165
- unmount() {
166
- this.disposed = true;
167
- if (this.container.renderTimer !== null) clearTimeout(this.container.renderTimer);
168
- this.eventBus.emit("willDisappear", void 0);
169
- reconciler.updateContainer(null, this.fiberRoot, null, () => {});
170
- this.eventBus.removeAllListeners();
171
- this.columns.clear();
172
- }
173
- };
174
- //#endregion
175
- export { TouchBarRoot };