@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.
- package/dist/action.js +0 -1
- package/dist/adapter/index.d.ts +2 -0
- package/dist/adapter/physical-device.d.ts +2 -0
- package/dist/adapter/physical-device.js +153 -0
- package/dist/adapter/types.d.ts +127 -0
- package/dist/devtools/bridge.d.ts +2 -2
- package/dist/devtools/bridge.js +7 -8
- package/dist/devtools/highlight.d.ts +1 -2
- package/dist/devtools/highlight.js +4 -3
- package/dist/devtools/types.d.ts +5 -5
- package/dist/hooks/animation.d.ts +1 -1
- package/dist/hooks/animation.js +2 -2
- package/dist/hooks/events.js +1 -1
- package/dist/hooks/sdk.js +11 -11
- package/dist/hooks/utility.js +3 -2
- package/dist/index.d.ts +3 -1
- package/dist/index.js +2 -1
- package/dist/plugin.js +69 -100
- package/dist/reconciler/vnode.d.ts +0 -2
- package/dist/reconciler/vnode.js +0 -1
- package/dist/render/cache.d.ts +5 -17
- package/dist/render/cache.js +7 -29
- package/dist/render/image-cache.d.ts +8 -7
- package/dist/render/image-cache.js +33 -17
- package/dist/render/metrics.d.ts +9 -10
- package/dist/render/metrics.js +36 -39
- package/dist/render/pipeline.d.ts +4 -14
- package/dist/render/pipeline.js +47 -111
- package/dist/render/png.d.ts +0 -9
- package/dist/render/png.js +5 -8
- package/dist/render/render-pool.d.ts +0 -2
- package/dist/render/render-pool.js +1 -12
- package/dist/roots/registry.d.ts +5 -9
- package/dist/roots/registry.js +10 -27
- package/dist/roots/root.d.ts +7 -34
- package/dist/roots/root.js +23 -90
- package/dist/roots/touchstrip-root.d.ts +6 -32
- package/dist/roots/touchstrip-root.js +61 -181
- package/dist/types.d.ts +23 -19
- package/package.json +6 -4
- package/dist/node_modules/.bun/xxhash-wasm@1.1.0/node_modules/xxhash-wasm/esm/xxhash-wasm.js +0 -3157
- package/dist/roots/flush-coordinator.d.ts +0 -18
- package/dist/roots/flush-coordinator.js +0 -38
package/dist/action.js
CHANGED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export type { StreamDeckAdapter, AdapterActionHandle, AdapterActionCallbacks, AdapterWillAppearEvent, AdapterActionDevice, AdapterController, AdapterCoordinates, AdapterSize, AdapterTriggerDescription, AdapterKeyDownPayload, AdapterKeyUpPayload, AdapterDialRotatePayload, AdapterDialPressPayload, AdapterTouchTapPayload, } from './types';
|
|
2
|
+
export { physicalDevice } from './physical-device';
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import streamDeck, { SingletonAction } from "@elgato/streamdeck";
|
|
2
|
+
//#region src/adapter/physical-device.ts
|
|
3
|
+
function wrapSdkAction(action) {
|
|
4
|
+
return {
|
|
5
|
+
id: action.id,
|
|
6
|
+
device: {
|
|
7
|
+
id: action.device.id,
|
|
8
|
+
type: action.device.type,
|
|
9
|
+
size: action.device.size,
|
|
10
|
+
name: action.device.name
|
|
11
|
+
},
|
|
12
|
+
controllerType: action.controllerType,
|
|
13
|
+
coordinates: "coordinates" in action ? action.coordinates : void 0,
|
|
14
|
+
async setImage(dataUri) {
|
|
15
|
+
if ("setImage" in action) await action.setImage(dataUri);
|
|
16
|
+
},
|
|
17
|
+
async setTitle(title) {
|
|
18
|
+
if ("setTitle" in action) await action.setTitle(title);
|
|
19
|
+
},
|
|
20
|
+
async showOk() {
|
|
21
|
+
if ("showOk" in action) await action.showOk();
|
|
22
|
+
},
|
|
23
|
+
async showAlert() {
|
|
24
|
+
await action.showAlert();
|
|
25
|
+
},
|
|
26
|
+
async setSettings(settings) {
|
|
27
|
+
await action.setSettings(settings);
|
|
28
|
+
},
|
|
29
|
+
async setFeedback(payload) {
|
|
30
|
+
if ("setFeedback" in action) await action.setFeedback(payload);
|
|
31
|
+
},
|
|
32
|
+
async setFeedbackLayout(layout) {
|
|
33
|
+
if ("setFeedbackLayout" in action) await action.setFeedbackLayout(layout);
|
|
34
|
+
},
|
|
35
|
+
async setTriggerDescription(hints) {
|
|
36
|
+
if ("setTriggerDescription" in action) await action.setTriggerDescription({
|
|
37
|
+
rotate: hints.rotate,
|
|
38
|
+
push: hints.push,
|
|
39
|
+
touch: hints.touch,
|
|
40
|
+
longTouch: hints.longTouch
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function physicalDevice() {
|
|
46
|
+
return {
|
|
47
|
+
pluginUUID: streamDeck.info.plugin.uuid,
|
|
48
|
+
async connect() {
|
|
49
|
+
await streamDeck.connect();
|
|
50
|
+
},
|
|
51
|
+
async getGlobalSettings() {
|
|
52
|
+
return streamDeck.settings.getGlobalSettings();
|
|
53
|
+
},
|
|
54
|
+
async setGlobalSettings(settings) {
|
|
55
|
+
await streamDeck.settings.setGlobalSettings(settings);
|
|
56
|
+
},
|
|
57
|
+
onGlobalSettingsChanged(callback) {
|
|
58
|
+
streamDeck.settings.onDidReceiveGlobalSettings((ev) => {
|
|
59
|
+
callback(ev.settings);
|
|
60
|
+
});
|
|
61
|
+
},
|
|
62
|
+
registerAction(uuid, callbacks) {
|
|
63
|
+
const singletonAction = new class extends SingletonAction {
|
|
64
|
+
manifestId = uuid;
|
|
65
|
+
onWillAppear(ev) {
|
|
66
|
+
callbacks.onWillAppear({
|
|
67
|
+
action: wrapSdkAction(ev.action),
|
|
68
|
+
payload: {
|
|
69
|
+
settings: ev.payload.settings,
|
|
70
|
+
controller: ev.payload.controller,
|
|
71
|
+
isInMultiAction: ev.payload.isInMultiAction
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
onWillDisappear(ev) {
|
|
76
|
+
callbacks.onWillDisappear(ev.action.id);
|
|
77
|
+
}
|
|
78
|
+
onKeyDown(ev) {
|
|
79
|
+
callbacks.onKeyDown(ev.action.id, {
|
|
80
|
+
settings: ev.payload.settings,
|
|
81
|
+
isInMultiAction: ev.payload.isInMultiAction,
|
|
82
|
+
state: ev.payload.state,
|
|
83
|
+
userDesiredState: "userDesiredState" in ev.payload ? ev.payload.userDesiredState : void 0
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
onKeyUp(ev) {
|
|
87
|
+
callbacks.onKeyUp(ev.action.id, {
|
|
88
|
+
settings: ev.payload.settings,
|
|
89
|
+
isInMultiAction: ev.payload.isInMultiAction,
|
|
90
|
+
state: ev.payload.state,
|
|
91
|
+
userDesiredState: "userDesiredState" in ev.payload ? ev.payload.userDesiredState : void 0
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
onDialRotate(ev) {
|
|
95
|
+
callbacks.onDialRotate(ev.action.id, {
|
|
96
|
+
ticks: ev.payload.ticks,
|
|
97
|
+
pressed: ev.payload.pressed,
|
|
98
|
+
settings: ev.payload.settings
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
onDialDown(ev) {
|
|
102
|
+
callbacks.onDialDown(ev.action.id, {
|
|
103
|
+
settings: ev.payload.settings,
|
|
104
|
+
controller: "Encoder"
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
onDialUp(ev) {
|
|
108
|
+
callbacks.onDialUp(ev.action.id, {
|
|
109
|
+
settings: ev.payload.settings,
|
|
110
|
+
controller: "Encoder"
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
onTouchTap(ev) {
|
|
114
|
+
callbacks.onTouchTap(ev.action.id, {
|
|
115
|
+
tapPos: ev.payload.tapPos,
|
|
116
|
+
hold: ev.payload.hold,
|
|
117
|
+
settings: ev.payload.settings
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
onDidReceiveSettings(ev) {
|
|
121
|
+
callbacks.onDidReceiveSettings(ev.action.id, ev.payload.settings);
|
|
122
|
+
}
|
|
123
|
+
onSendToPlugin(ev) {
|
|
124
|
+
callbacks.onSendToPlugin(ev.action.id, ev.payload);
|
|
125
|
+
}
|
|
126
|
+
onPropertyInspectorDidAppear(ev) {
|
|
127
|
+
callbacks.onPropertyInspectorDidAppear(ev.action.id);
|
|
128
|
+
}
|
|
129
|
+
onPropertyInspectorDidDisappear(ev) {
|
|
130
|
+
callbacks.onPropertyInspectorDidDisappear(ev.action.id);
|
|
131
|
+
}
|
|
132
|
+
onTitleParametersDidChange(ev) {
|
|
133
|
+
callbacks.onTitleParametersDidChange(ev.action.id, {
|
|
134
|
+
title: ev.payload.title,
|
|
135
|
+
settings: ev.payload.settings
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
}();
|
|
139
|
+
streamDeck.actions.registerAction(singletonAction);
|
|
140
|
+
},
|
|
141
|
+
async openUrl(url) {
|
|
142
|
+
await streamDeck.system.openUrl(url);
|
|
143
|
+
},
|
|
144
|
+
async switchToProfile(deviceId, profile) {
|
|
145
|
+
await streamDeck.profiles.switchToProfile(deviceId, profile);
|
|
146
|
+
},
|
|
147
|
+
async sendToPropertyInspector(payload) {
|
|
148
|
+
await streamDeck.ui.sendToPropertyInspector(payload);
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
//#endregion
|
|
153
|
+
export { physicalDevice };
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { JsonObject, JsonValue } from '@elgato/utils';
|
|
2
|
+
/** Controller surface type. Matches SDK Controller values exactly. */
|
|
3
|
+
export type AdapterController = "Keypad" | "Encoder";
|
|
4
|
+
/** Grid coordinates for a key or encoder on a device. */
|
|
5
|
+
export interface AdapterCoordinates {
|
|
6
|
+
readonly column: number;
|
|
7
|
+
readonly row: number;
|
|
8
|
+
}
|
|
9
|
+
/** Device grid size (number of key columns and rows). */
|
|
10
|
+
export interface AdapterSize {
|
|
11
|
+
readonly columns: number;
|
|
12
|
+
readonly rows: number;
|
|
13
|
+
}
|
|
14
|
+
/** Hint labels for dial/encoder trigger zones shown on the Stream Deck LCD. */
|
|
15
|
+
export interface AdapterTriggerDescription {
|
|
16
|
+
rotate?: string;
|
|
17
|
+
push?: string;
|
|
18
|
+
touch?: string;
|
|
19
|
+
longTouch?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface AdapterActionHandle {
|
|
22
|
+
readonly id: string;
|
|
23
|
+
readonly device: AdapterActionDevice;
|
|
24
|
+
readonly controllerType: AdapterController;
|
|
25
|
+
readonly coordinates?: AdapterCoordinates;
|
|
26
|
+
/** Push a rendered data URI to the key display. No-op on encoder surfaces. */
|
|
27
|
+
setImage(dataUri: string): Promise<void>;
|
|
28
|
+
/** Set the key title overlay. No-op on encoder surfaces. */
|
|
29
|
+
setTitle(title: string): Promise<void>;
|
|
30
|
+
/** Flash the OK checkmark on the key. No-op on encoder surfaces. */
|
|
31
|
+
showOk(): Promise<void>;
|
|
32
|
+
/** Flash the alert triangle on the action. */
|
|
33
|
+
showAlert(): Promise<void>;
|
|
34
|
+
/** Persist action settings to the Stream Deck. */
|
|
35
|
+
setSettings(settings: JsonObject): Promise<void>;
|
|
36
|
+
/** Push dial/touchstrip feedback payload. No-op on key surfaces. */
|
|
37
|
+
setFeedback(payload: Record<string, unknown>): Promise<void>;
|
|
38
|
+
/** Set the encoder feedback layout (JSON or layout ID). No-op on key surfaces. */
|
|
39
|
+
setFeedbackLayout(layout: string | Record<string, unknown>): Promise<void>;
|
|
40
|
+
/** Set dial hint text (rotate, push, touch labels). No-op on key surfaces. */
|
|
41
|
+
setTriggerDescription(hints: AdapterTriggerDescription): Promise<void>;
|
|
42
|
+
}
|
|
43
|
+
/** Device info as seen from an action event. */
|
|
44
|
+
export interface AdapterActionDevice {
|
|
45
|
+
readonly id: string;
|
|
46
|
+
/**
|
|
47
|
+
* Numeric device type matching Elgato DeviceType enum values.
|
|
48
|
+
* Using `number` instead of the SDK's enum avoids coupling to specific
|
|
49
|
+
* device models while remaining compatible with the KEY_SIZES lookup
|
|
50
|
+
* table in registry.ts.
|
|
51
|
+
*/
|
|
52
|
+
readonly type: number;
|
|
53
|
+
readonly size: AdapterSize;
|
|
54
|
+
readonly name: string;
|
|
55
|
+
}
|
|
56
|
+
/** Event payload provided to onWillAppear callbacks. */
|
|
57
|
+
export interface AdapterWillAppearEvent {
|
|
58
|
+
action: AdapterActionHandle;
|
|
59
|
+
payload: {
|
|
60
|
+
settings: JsonObject;
|
|
61
|
+
controller: AdapterController;
|
|
62
|
+
isInMultiAction: boolean;
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
export interface AdapterKeyDownPayload {
|
|
66
|
+
settings: JsonObject;
|
|
67
|
+
isInMultiAction: boolean;
|
|
68
|
+
state?: number;
|
|
69
|
+
userDesiredState?: number;
|
|
70
|
+
}
|
|
71
|
+
export interface AdapterKeyUpPayload {
|
|
72
|
+
settings: JsonObject;
|
|
73
|
+
isInMultiAction: boolean;
|
|
74
|
+
state?: number;
|
|
75
|
+
userDesiredState?: number;
|
|
76
|
+
}
|
|
77
|
+
export interface AdapterDialRotatePayload {
|
|
78
|
+
ticks: number;
|
|
79
|
+
pressed: boolean;
|
|
80
|
+
settings: JsonObject;
|
|
81
|
+
}
|
|
82
|
+
export interface AdapterDialPressPayload {
|
|
83
|
+
settings: JsonObject;
|
|
84
|
+
controller: "Encoder";
|
|
85
|
+
}
|
|
86
|
+
export interface AdapterTouchTapPayload {
|
|
87
|
+
tapPos: [x: number, y: number];
|
|
88
|
+
hold: boolean;
|
|
89
|
+
settings: JsonObject;
|
|
90
|
+
}
|
|
91
|
+
export interface AdapterActionCallbacks {
|
|
92
|
+
onWillAppear(ev: AdapterWillAppearEvent): void;
|
|
93
|
+
onWillDisappear(actionId: string): void;
|
|
94
|
+
onKeyDown(actionId: string, payload: AdapterKeyDownPayload): void;
|
|
95
|
+
onKeyUp(actionId: string, payload: AdapterKeyUpPayload): void;
|
|
96
|
+
onDialRotate(actionId: string, payload: AdapterDialRotatePayload): void;
|
|
97
|
+
onDialDown(actionId: string, payload: AdapterDialPressPayload): void;
|
|
98
|
+
onDialUp(actionId: string, payload: AdapterDialPressPayload): void;
|
|
99
|
+
onTouchTap(actionId: string, payload: AdapterTouchTapPayload): void;
|
|
100
|
+
onDidReceiveSettings(actionId: string, settings: JsonObject): void;
|
|
101
|
+
onSendToPlugin(actionId: string, payload: JsonValue): void;
|
|
102
|
+
onPropertyInspectorDidAppear(actionId: string): void;
|
|
103
|
+
onPropertyInspectorDidDisappear(actionId: string): void;
|
|
104
|
+
onTitleParametersDidChange(actionId: string, payload: {
|
|
105
|
+
title: string;
|
|
106
|
+
settings: JsonObject;
|
|
107
|
+
}): void;
|
|
108
|
+
}
|
|
109
|
+
export interface StreamDeckAdapter {
|
|
110
|
+
/** Plugin UUID, used for devtools identification. */
|
|
111
|
+
readonly pluginUUID: string;
|
|
112
|
+
/** Initialize the adapter and connect to the backend. */
|
|
113
|
+
connect(): Promise<void>;
|
|
114
|
+
/** Retrieve plugin-wide global settings. */
|
|
115
|
+
getGlobalSettings<T extends JsonObject = JsonObject>(): Promise<T>;
|
|
116
|
+
/** Persist plugin-wide global settings. */
|
|
117
|
+
setGlobalSettings<T extends JsonObject = JsonObject>(settings: T): Promise<void>;
|
|
118
|
+
/** Subscribe to external global settings changes (e.g. from Property Inspector). */
|
|
119
|
+
onGlobalSettingsChanged(callback: (settings: JsonObject) => void): void;
|
|
120
|
+
registerAction(uuid: string, callbacks: AdapterActionCallbacks): void;
|
|
121
|
+
/** Open a URL in the user's default browser. */
|
|
122
|
+
openUrl(url: string): Promise<void>;
|
|
123
|
+
/** Switch the active Stream Deck profile. */
|
|
124
|
+
switchToProfile(deviceId: string, profile: string): Promise<void>;
|
|
125
|
+
/** Send a payload to the Property Inspector. */
|
|
126
|
+
sendToPropertyInspector(payload: JsonValue): Promise<void>;
|
|
127
|
+
}
|
|
@@ -63,7 +63,7 @@ export declare class DevtoolsBridge implements RegistryObserver {
|
|
|
63
63
|
private static readonly TB_PREFIX;
|
|
64
64
|
private handleHighlight;
|
|
65
65
|
/**
|
|
66
|
-
* Restore a highlighted action or
|
|
66
|
+
* Restore a highlighted action or TouchStrip to its normal state.
|
|
67
67
|
* Un-suppresses hardware pushes and restores the original image(s).
|
|
68
68
|
*/
|
|
69
69
|
private restoreHighlight;
|
|
@@ -73,7 +73,7 @@ export declare class DevtoolsBridge implements RegistryObserver {
|
|
|
73
73
|
private broadcastHighlightRender;
|
|
74
74
|
/**
|
|
75
75
|
* Clear highlight URIs for the given actionId.
|
|
76
|
-
* For
|
|
76
|
+
* For TouchStrip IDs, clears all per-segment keys (touchStrip:*:seg:N).
|
|
77
77
|
* For regular actions, clears the single actionId key.
|
|
78
78
|
*/
|
|
79
79
|
private broadcastHighlightClear;
|
package/dist/devtools/bridge.js
CHANGED
|
@@ -141,7 +141,7 @@ var DevtoolsBridge = class DevtoolsBridge {
|
|
|
141
141
|
columns: /* @__PURE__ */ new Map()
|
|
142
142
|
});
|
|
143
143
|
this.eventBusOwners.set(root.eventBus, {
|
|
144
|
-
actionId: `
|
|
144
|
+
actionId: `touchStrip:${deviceId}`,
|
|
145
145
|
uuid: ""
|
|
146
146
|
});
|
|
147
147
|
}
|
|
@@ -339,8 +339,7 @@ var DevtoolsBridge = class DevtoolsBridge {
|
|
|
339
339
|
/** Convert internal RenderProfile to wire-protocol ProfileData. */
|
|
340
340
|
toProfileData(profile) {
|
|
341
341
|
return {
|
|
342
|
-
|
|
343
|
-
fromJsxMs: profile.fromJsxMs,
|
|
342
|
+
vnodeConversionMs: profile.vnodeConversionMs,
|
|
344
343
|
takumiRenderMs: profile.takumiRenderMs,
|
|
345
344
|
hashMs: profile.hashMs,
|
|
346
345
|
base64Ms: profile.base64Ms,
|
|
@@ -363,7 +362,7 @@ var DevtoolsBridge = class DevtoolsBridge {
|
|
|
363
362
|
});
|
|
364
363
|
}
|
|
365
364
|
const msg = {
|
|
366
|
-
type: "render:
|
|
365
|
+
type: "render:touchStrip",
|
|
367
366
|
ts: Date.now(),
|
|
368
367
|
deviceId,
|
|
369
368
|
canvas: {
|
|
@@ -377,7 +376,7 @@ var DevtoolsBridge = class DevtoolsBridge {
|
|
|
377
376
|
};
|
|
378
377
|
this.server.broadcast(msg);
|
|
379
378
|
}
|
|
380
|
-
static TB_PREFIX = "
|
|
379
|
+
static TB_PREFIX = "touchStrip:";
|
|
381
380
|
async handleHighlight(actionId, nodeId) {
|
|
382
381
|
try {
|
|
383
382
|
const prevId = this.highlightedActionId;
|
|
@@ -419,7 +418,7 @@ var DevtoolsBridge = class DevtoolsBridge {
|
|
|
419
418
|
} catch {}
|
|
420
419
|
}
|
|
421
420
|
/**
|
|
422
|
-
* Restore a highlighted action or
|
|
421
|
+
* Restore a highlighted action or TouchStrip to its normal state.
|
|
423
422
|
* Un-suppresses hardware pushes and restores the original image(s).
|
|
424
423
|
*/
|
|
425
424
|
async restoreHighlight(id) {
|
|
@@ -454,7 +453,7 @@ var DevtoolsBridge = class DevtoolsBridge {
|
|
|
454
453
|
const segmentWidth = 200;
|
|
455
454
|
const segmentHeight = 100;
|
|
456
455
|
const fullWidth = (Math.max(...columns) + 1) * segmentWidth;
|
|
457
|
-
const result = await renderTouchStripWithHighlight(tb.root.vcontainer, fullWidth, segmentHeight, columns, segmentWidth, this.renderConfig
|
|
456
|
+
const result = await renderTouchStripWithHighlight(tb.root.vcontainer, fullWidth, segmentHeight, columns, segmentWidth, this.renderConfig, nodeId);
|
|
458
457
|
if (result && this.highlightedActionId === actionId && this.highlightedNodeId === nodeId) {
|
|
459
458
|
await tb.root.pushSegmentImages(result.segmentUris);
|
|
460
459
|
for (const [col, uri] of result.segmentUris) this.broadcastHighlightRender(`${actionId}:seg:${col}`, uri);
|
|
@@ -473,7 +472,7 @@ var DevtoolsBridge = class DevtoolsBridge {
|
|
|
473
472
|
}
|
|
474
473
|
/**
|
|
475
474
|
* Clear highlight URIs for the given actionId.
|
|
476
|
-
* For
|
|
475
|
+
* For TouchStrip IDs, clears all per-segment keys (touchStrip:*:seg:N).
|
|
477
476
|
* For regular actions, clears the single actionId key.
|
|
478
477
|
*/
|
|
479
478
|
broadcastHighlightClear(id) {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { OutputFormat } from '@takumi-rs/core';
|
|
2
1
|
import { VContainer } from '../reconciler/vnode';
|
|
3
2
|
import { RenderConfig } from '../render/pipeline';
|
|
4
3
|
export declare function renderWithHighlight(container: VContainer, width: number, height: number, config: RenderConfig, targetNid: number): Promise<string | null>;
|
|
@@ -6,4 +5,4 @@ export interface TouchStripHighlightResult {
|
|
|
6
5
|
/** Per-column data URIs for ALL segments. */
|
|
7
6
|
segmentUris: Map<number, string>;
|
|
8
7
|
}
|
|
9
|
-
export declare function renderTouchStripWithHighlight(container: VContainer, fullWidth: number, segmentHeight: number, columns: number[], segmentWidth: number,
|
|
8
|
+
export declare function renderTouchStripWithHighlight(container: VContainer, fullWidth: number, segmentHeight: number, columns: number[], segmentWidth: number, config: RenderConfig, targetNid: number): Promise<TouchStripHighlightResult | null>;
|
|
@@ -18,7 +18,8 @@ async function renderWithHighlight(container, width, height, config, targetNid)
|
|
|
18
18
|
devicePixelRatio: config.devicePixelRatio
|
|
19
19
|
}), config.imageFormat);
|
|
20
20
|
}
|
|
21
|
-
|
|
21
|
+
var TOUCHSTRIP_HIGHLIGHT_FORMAT = "png";
|
|
22
|
+
async function renderTouchStripWithHighlight(container, fullWidth, segmentHeight, columns, segmentWidth, config, targetNid) {
|
|
22
23
|
if (container.children.length === 0) return null;
|
|
23
24
|
const effectiveNid = resolveTargetNid(container, targetNid);
|
|
24
25
|
const rootNode = buildTakumiRoot(container);
|
|
@@ -50,10 +51,10 @@ async function renderTouchStripWithHighlight(container, fullWidth, segmentHeight
|
|
|
50
51
|
const segBuffer = await config.renderer.render(clipNode, {
|
|
51
52
|
width: segmentWidth,
|
|
52
53
|
height: segmentHeight,
|
|
53
|
-
format,
|
|
54
|
+
format: TOUCHSTRIP_HIGHLIGHT_FORMAT,
|
|
54
55
|
devicePixelRatio: config.devicePixelRatio
|
|
55
56
|
});
|
|
56
|
-
segmentUris.set(column, bufferToDataUri(segBuffer,
|
|
57
|
+
segmentUris.set(column, bufferToDataUri(segBuffer, TOUCHSTRIP_HIGHLIGHT_FORMAT));
|
|
57
58
|
});
|
|
58
59
|
await Promise.all(segmentPromises);
|
|
59
60
|
return { segmentUris };
|
package/dist/devtools/types.d.ts
CHANGED
|
@@ -150,7 +150,7 @@ export interface RenderMessage extends BaseMessage {
|
|
|
150
150
|
profile?: ProfileData;
|
|
151
151
|
}
|
|
152
152
|
export interface TouchStripRenderMessage extends BaseMessage {
|
|
153
|
-
type: "render:
|
|
153
|
+
type: "render:touchStrip";
|
|
154
154
|
deviceId: string;
|
|
155
155
|
canvas: {
|
|
156
156
|
width: number;
|
|
@@ -179,7 +179,7 @@ export interface LifecycleMessage extends BaseMessage {
|
|
|
179
179
|
event: "appear" | "disappear";
|
|
180
180
|
actionId: string;
|
|
181
181
|
actionUuid: string;
|
|
182
|
-
surface: "key" | "dial" | "touch" | "
|
|
182
|
+
surface: "key" | "dial" | "touch" | "touchStrip";
|
|
183
183
|
device: {
|
|
184
184
|
id: string;
|
|
185
185
|
type: number;
|
|
@@ -203,8 +203,8 @@ export interface HighlightRenderMessage extends BaseMessage {
|
|
|
203
203
|
}
|
|
204
204
|
/** Per-render pipeline timing data, embedded in RenderMessage. */
|
|
205
205
|
export interface ProfileData {
|
|
206
|
-
|
|
207
|
-
|
|
206
|
+
/** Time to convert VNode tree to Takumi node tree (ms). */
|
|
207
|
+
vnodeConversionMs: number;
|
|
208
208
|
takumiRenderMs: number;
|
|
209
209
|
hashMs: number;
|
|
210
210
|
base64Ms: number;
|
|
@@ -234,7 +234,7 @@ export interface MetricsData {
|
|
|
234
234
|
/** Image cache memory usage in bytes. */
|
|
235
235
|
imageCacheBytes: number;
|
|
236
236
|
/** TouchStrip cache memory usage in bytes. */
|
|
237
|
-
|
|
237
|
+
touchStripCacheBytes: number;
|
|
238
238
|
}
|
|
239
239
|
export interface MetricsMessage extends BaseMessage {
|
|
240
240
|
type: "metrics";
|
|
@@ -35,7 +35,7 @@ export interface TweenConfig {
|
|
|
35
35
|
duration: number;
|
|
36
36
|
/** Easing function name or custom (t: number) => number. @default "easeOut" */
|
|
37
37
|
easing: EasingName | EasingFn;
|
|
38
|
-
/** Target FPS for the animation tick loop. @default
|
|
38
|
+
/** Target FPS for the animation tick loop. @default 30 */
|
|
39
39
|
fps: number;
|
|
40
40
|
}
|
|
41
41
|
export interface TweenResult<T extends AnimationTarget> {
|
package/dist/hooks/animation.js
CHANGED
|
@@ -12,7 +12,7 @@ var SPRING_DEFAULTS = {
|
|
|
12
12
|
var TWEEN_DEFAULTS = {
|
|
13
13
|
duration: 300,
|
|
14
14
|
easing: "easeOut",
|
|
15
|
-
fps:
|
|
15
|
+
fps: 30
|
|
16
16
|
};
|
|
17
17
|
/** Max dt cap to prevent spring explosion after long pauses.
|
|
18
18
|
* If the process is suspended (debugger, GC pause), dt could be
|
|
@@ -196,7 +196,7 @@ function useSpring(target, config) {
|
|
|
196
196
|
config?.displacementThreshold,
|
|
197
197
|
config?.clamp
|
|
198
198
|
]);
|
|
199
|
-
const fps = config?.fps ??
|
|
199
|
+
const fps = config?.fps ?? 30;
|
|
200
200
|
const isObject = typeof target === "object" && target !== null;
|
|
201
201
|
const stateRef = useRef(null);
|
|
202
202
|
if (stateRef.current === null) stateRef.current = initializeSpringState(target);
|
package/dist/hooks/events.js
CHANGED
|
@@ -38,7 +38,7 @@ function useTouchTap(callback) {
|
|
|
38
38
|
function useDialHint(hints) {
|
|
39
39
|
const { action } = useContext(StreamDeckContext);
|
|
40
40
|
useEffect(() => {
|
|
41
|
-
|
|
41
|
+
action.setTriggerDescription({
|
|
42
42
|
rotate: hints.rotate,
|
|
43
43
|
push: hints.press,
|
|
44
44
|
touch: hints.touch,
|
package/dist/hooks/sdk.js
CHANGED
|
@@ -3,23 +3,23 @@ import { useCallbackRef } from "./internal/useCallbackRef.js";
|
|
|
3
3
|
import { useCallback, useContext, useEffect } from "react";
|
|
4
4
|
//#region src/hooks/sdk.ts
|
|
5
5
|
function useOpenUrl() {
|
|
6
|
-
const {
|
|
6
|
+
const { adapter } = useContext(StreamDeckContext);
|
|
7
7
|
return useCallback(async (url) => {
|
|
8
|
-
await
|
|
9
|
-
}, [
|
|
8
|
+
await adapter.openUrl(url);
|
|
9
|
+
}, [adapter]);
|
|
10
10
|
}
|
|
11
11
|
function useSwitchProfile() {
|
|
12
|
-
const {
|
|
12
|
+
const { adapter, action } = useContext(StreamDeckContext);
|
|
13
13
|
return useCallback(async (profile, deviceId) => {
|
|
14
14
|
const devId = deviceId ?? action.device.id;
|
|
15
|
-
await
|
|
16
|
-
}, [
|
|
15
|
+
await adapter.switchToProfile(devId, profile);
|
|
16
|
+
}, [adapter, action]);
|
|
17
17
|
}
|
|
18
18
|
function useSendToPI() {
|
|
19
|
-
const {
|
|
19
|
+
const { adapter } = useContext(StreamDeckContext);
|
|
20
20
|
return useCallback(async (payload) => {
|
|
21
|
-
await
|
|
22
|
-
}, [
|
|
21
|
+
await adapter.sendToPropertyInspector(payload);
|
|
22
|
+
}, [adapter]);
|
|
23
23
|
}
|
|
24
24
|
function usePropertyInspector(callback) {
|
|
25
25
|
const bus = useContext(EventBusContext);
|
|
@@ -41,13 +41,13 @@ function useShowAlert() {
|
|
|
41
41
|
function useShowOk() {
|
|
42
42
|
const { action } = useContext(StreamDeckContext);
|
|
43
43
|
return useCallback(async () => {
|
|
44
|
-
|
|
44
|
+
await action.showOk();
|
|
45
45
|
}, [action]);
|
|
46
46
|
}
|
|
47
47
|
function useTitle() {
|
|
48
48
|
const { action } = useContext(StreamDeckContext);
|
|
49
49
|
return useCallback(async (title) => {
|
|
50
|
-
|
|
50
|
+
await action.setTitle(title);
|
|
51
51
|
}, [action]);
|
|
52
52
|
}
|
|
53
53
|
//#endregion
|
package/dist/hooks/utility.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { useCallbackRef } from "./internal/useCallbackRef.js";
|
|
2
2
|
import { useCallback, useEffect, useMemo, useRef } from "react";
|
|
3
3
|
//#region src/hooks/utility.ts
|
|
4
|
-
var DEFAULT_TICK_FPS =
|
|
4
|
+
var DEFAULT_TICK_FPS = 30;
|
|
5
|
+
var MAX_TICK_FPS = 30;
|
|
5
6
|
function toTickIntervalMs(fps) {
|
|
6
7
|
if (!Number.isFinite(fps) || fps <= 0) return Math.round(1e3 / DEFAULT_TICK_FPS);
|
|
7
|
-
return Math.max(1, Math.round(1e3 / fps));
|
|
8
|
+
return Math.max(1, Math.round(1e3 / Math.min(fps, MAX_TICK_FPS)));
|
|
8
9
|
}
|
|
9
10
|
function useInterval(callback, delayMs) {
|
|
10
11
|
const callbackRef = useCallbackRef(callback);
|
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,8 @@ export { defineAction } from './action';
|
|
|
3
3
|
export type { RenderProfile } from './render/pipeline';
|
|
4
4
|
export type { CacheStats } from './render/image-cache';
|
|
5
5
|
export type { RenderMetrics } from './render/metrics';
|
|
6
|
+
export { physicalDevice } from './adapter/physical-device';
|
|
7
|
+
export type { StreamDeckAdapter, AdapterActionHandle, AdapterActionCallbacks, AdapterWillAppearEvent, AdapterActionDevice, AdapterController, AdapterCoordinates, AdapterSize, AdapterTriggerDescription, } from './adapter/types';
|
|
6
8
|
export { useKeyDown, useKeyUp, useDialRotate, useDialDown, useDialUp, useTouchTap, useDialHint, } from './hooks/events';
|
|
7
9
|
export { useTap, useLongPress, useDoubleTap } from './hooks/gestures';
|
|
8
10
|
export { useSettings, useGlobalSettings } from './hooks/settings';
|
|
@@ -21,7 +23,7 @@ export { ProgressBar } from './components/ProgressBar';
|
|
|
21
23
|
export { CircularGauge } from './components/CircularGauge';
|
|
22
24
|
export { ErrorBoundary } from './components/ErrorBoundary';
|
|
23
25
|
export { tw } from './tw/index';
|
|
24
|
-
export type { PluginConfig, FontConfig, ActionConfig, ActionConfigInput, ActionDefinition, ActionUUID, ManifestActions, EncoderLayout, WrapperComponent, DeviceInfo, ActionInfo, CanvasInfo, TouchStripLayout, TouchStripLayoutItem, KeyDownPayload, KeyUpPayload, DialRotatePayload, DialPressPayload, TouchTapPayload, DialHints, StreamDeckAccess, TouchStripInfo, TouchStripTapPayload, TouchStripDialRotatePayload, TouchStripDialPressPayload, } from './types';
|
|
26
|
+
export type { PluginConfig, FontConfig, ActionConfig, ActionConfigInput, ActionDefinition, ActionUUID, ManifestActions, EncoderLayout, WrapperComponent, Controller, Coordinates, Size, DeviceInfo, ActionInfo, CanvasInfo, TouchStripLayout, TouchStripLayoutItem, KeyDownPayload, KeyUpPayload, DialRotatePayload, DialPressPayload, TouchTapPayload, DialHints, StreamDeckAccess, TouchStripInfo, TouchStripTapPayload, TouchStripDialRotatePayload, TouchStripDialPressPayload, } from './types';
|
|
25
27
|
export type { TapOptions, LongPressOptions, DoubleTapOptions } from './hooks/gestures';
|
|
26
28
|
export type { BoxProps } from './components/Box';
|
|
27
29
|
export type { TextProps } from './components/Text';
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { physicalDevice } from "./adapter/physical-device.js";
|
|
1
2
|
import { createPlugin } from "./plugin.js";
|
|
2
3
|
import { defineAction } from "./action.js";
|
|
3
4
|
import { useDialDown, useDialHint, useDialRotate, useDialUp, useKeyDown, useKeyUp, useTouchTap } from "./hooks/events.js";
|
|
@@ -17,4 +18,4 @@ import { ProgressBar } from "./components/ProgressBar.js";
|
|
|
17
18
|
import { CircularGauge } from "./components/CircularGauge.js";
|
|
18
19
|
import { ErrorBoundary } from "./components/ErrorBoundary.js";
|
|
19
20
|
import { tw } from "./tw/index.js";
|
|
20
|
-
export { Box, CircularGauge, Easings, ErrorBoundary, Icon, Image, ProgressBar, SpringPresets, Text, createPlugin, defineAction, tw, useAction, useCanvas, useDevice, useDialDown, useDialHint, useDialRotate, useDialUp, useDoubleTap, useGlobalSettings, useInterval, useKeyDown, useKeyUp, useLongPress, useOpenUrl, usePrevious, usePropertyInspector, useSendToPI, useSettings, useShowAlert, useShowOk, useSpring, useStreamDeck, useSwitchProfile, useTap, useTick, useTimeout, useTitle, useTouchStrip, useTouchStripDialDown, useTouchStripDialRotate, useTouchStripDialUp, useTouchStripTap, useTouchTap, useTween, useWillAppear, useWillDisappear };
|
|
21
|
+
export { Box, CircularGauge, Easings, ErrorBoundary, Icon, Image, ProgressBar, SpringPresets, Text, createPlugin, defineAction, physicalDevice, tw, useAction, useCanvas, useDevice, useDialDown, useDialHint, useDialRotate, useDialUp, useDoubleTap, useGlobalSettings, useInterval, useKeyDown, useKeyUp, useLongPress, useOpenUrl, usePrevious, usePropertyInspector, useSendToPI, useSettings, useShowAlert, useShowOk, useSpring, useStreamDeck, useSwitchProfile, useTap, useTick, useTimeout, useTitle, useTouchStrip, useTouchStripDialDown, useTouchStripDialRotate, useTouchStripDialUp, useTouchStripTap, useTouchTap, useTween, useWillAppear, useWillDisappear };
|