Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/free-oranges-lose.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@elgato/streamdeck": major
---

`KeyAction` and `DialAction` types now require their setting type be defined.
Comment thread
GeekyEggo marked this conversation as resolved.
Outdated
5 changes: 5 additions & 0 deletions .changeset/wild-bikes-vanish.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@elgato/streamdeck": major
---

Fixed type-narrowing when calling `setSettings` on an event's action.
41 changes: 20 additions & 21 deletions packages/plugin/src/plugin/actions/__tests__/service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ describe("actions", () => {
// Assert (emit).
expect(listener).toHaveBeenCalledTimes(1);
expect(listener).toHaveBeenCalledWith<[DialDownEvent<Settings>]>({
action: actionStore.getActionById(ev.context) as DialAction,
action: actionStore.getActionById(ev.context) as DialAction<JsonObject>,
payload: ev.payload,
type: "dialDown",
});
Expand Down Expand Up @@ -153,7 +153,7 @@ describe("actions", () => {
// Assert (emit).
expect(listener).toHaveBeenCalledTimes(1);
expect(listener).toHaveBeenCalledWith<[DialRotateEvent<Settings>]>({
action: actionStore.getActionById(ev.context) as DialAction,
action: actionStore.getActionById(ev.context) as DialAction<JsonObject>,
payload: ev.payload,
type: "dialRotate",
});
Expand Down Expand Up @@ -197,7 +197,7 @@ describe("actions", () => {
// Assert (emit).
expect(listener).toHaveBeenCalledTimes(1);
expect(listener).toHaveBeenCalledWith<[DialUpEvent<Settings>]>({
action: actionStore.getActionById(ev.context) as DialAction,
action: actionStore.getActionById(ev.context) as DialAction<JsonObject>,
payload: ev.payload,
type: "dialUp",
});
Expand Down Expand Up @@ -242,7 +242,7 @@ describe("actions", () => {
// Assert (emit).
expect(listener).toHaveBeenCalledTimes(1);
expect(listener).toHaveBeenCalledWith<[KeyDownEvent<Settings>]>({
action: actionStore.getActionById(ev.context) as KeyAction,
action: actionStore.getActionById(ev.context) as KeyAction<JsonObject>,
payload: ev.payload,
type: "keyDown",
});
Expand Down Expand Up @@ -287,7 +287,7 @@ describe("actions", () => {
// Assert (emit).
expect(listener).toHaveBeenCalledTimes(1);
expect(listener).toHaveBeenCalledWith<[KeyUpEvent<Settings>]>({
action: actionStore.getActionById(ev.context) as KeyAction,
action: actionStore.getActionById(ev.context) as KeyAction<JsonObject>,
payload: ev.payload,
type: "keyUp",
});
Expand Down Expand Up @@ -341,7 +341,7 @@ describe("actions", () => {
// Assert (emit).
expect(listener).toHaveBeenCalledTimes(1);
expect(listener).toHaveBeenCalledWith<[TitleParametersDidChangeEvent<Settings>]>({
action: actionStore.getActionById(ev.context) as KeyAction,
action: actionStore.getActionById(ev.context) as KeyAction<JsonObject>,
payload: ev.payload,
type: "titleParametersDidChange",
});
Expand Down Expand Up @@ -387,7 +387,7 @@ describe("actions", () => {
// Assert (emit).
expect(listener).toHaveBeenCalledTimes(1);
expect(listener).toHaveBeenCalledWith<[TouchTapEvent<Settings>]>({
action: actionStore.getActionById(ev.context) as DialAction,
action: actionStore.getActionById(ev.context) as DialAction<JsonObject>,
payload: ev.payload,
type: "touchTap",
});
Expand Down Expand Up @@ -432,7 +432,7 @@ describe("actions", () => {
// Assert (emit).
expect(listener).toHaveBeenCalledTimes(1);
expect(listener).toHaveBeenCalledWith<[WillAppearEvent<Settings>]>({
action: actionStore.getActionById(ev.context) as KeyAction,
action: actionStore.getActionById(ev.context) as KeyAction<JsonObject>,
payload: ev.payload,
type: "willAppear",
});
Expand Down Expand Up @@ -490,7 +490,6 @@ describe("actions", () => {
expect(listener).toHaveBeenCalledTimes(1);
});


/**
* Asserts settings cache lifecycle updates for appear, settings updates, and disappear events.
*/
Expand Down Expand Up @@ -668,7 +667,7 @@ describe("actions", () => {
// Assert.
expect(listener).toHaveBeenCalledTimes(1);
expect(listener).toHaveBeenCalledWith<[DialDownEvent<Settings>]>({
action: actionStore.getActionById(ev.context) as DialAction,
action: actionStore.getActionById(ev.context) as DialAction<JsonObject>,
payload: ev.payload,
type: "dialDown",
});
Expand Down Expand Up @@ -712,7 +711,7 @@ describe("actions", () => {
// Assert.
expect(listener).toHaveBeenCalledTimes(1);
expect(listener).toHaveBeenCalledWith<[DialRotateEvent<Settings>]>({
action: actionStore.getActionById(ev.context) as DialAction,
action: actionStore.getActionById(ev.context) as DialAction<JsonObject>,
payload: ev.payload,
type: "dialRotate",
});
Expand Down Expand Up @@ -754,7 +753,7 @@ describe("actions", () => {
// Assert.
expect(listener).toHaveBeenCalledTimes(1);
expect(listener).toHaveBeenCalledWith<[DialUpEvent<Settings>]>({
action: actionStore.getActionById(ev.context) as DialAction,
action: actionStore.getActionById(ev.context) as DialAction<JsonObject>,
payload: ev.payload,
type: "dialUp",
});
Expand Down Expand Up @@ -787,7 +786,7 @@ describe("actions", () => {
// Assert.
expect(listener).toHaveBeenCalledTimes(1);
expect(listener).toHaveBeenCalledWith<[SendToPluginEvent<Settings, Settings>]>({
action: actionStore.getActionById(ev.context) as KeyAction,
action: actionStore.getActionById(ev.context) as KeyAction<JsonObject>,
payload: {
name: "Hello world",
},
Expand Down Expand Up @@ -832,7 +831,7 @@ describe("actions", () => {
// Assert.
expect(listener).toHaveBeenCalledTimes(1);
expect(listener).toHaveBeenCalledWith<[DidReceiveSettingsEvent<Settings>]>({
action: actionStore.getActionById(ev.context) as KeyAction,
action: actionStore.getActionById(ev.context) as KeyAction<JsonObject>,
payload: ev.payload,
type: "didReceiveSettings",
});
Expand Down Expand Up @@ -875,7 +874,7 @@ describe("actions", () => {
// Assert.
expect(listener).toHaveBeenCalledTimes(1);
expect(listener).toHaveBeenCalledWith<[KeyDownEvent<Settings>]>({
action: actionStore.getActionById(ev.context) as KeyAction,
action: actionStore.getActionById(ev.context) as KeyAction<JsonObject>,
payload: ev.payload,
type: "keyDown",
});
Expand Down Expand Up @@ -918,7 +917,7 @@ describe("actions", () => {
// Assert.
expect(listener).toHaveBeenCalledTimes(1);
expect(listener).toHaveBeenCalledWith<[KeyUpEvent<Settings>]>({
action: actionStore.getActionById(ev.context) as KeyAction,
action: actionStore.getActionById(ev.context) as KeyAction<JsonObject>,
payload: ev.payload,
type: "keyUp",
});
Expand Down Expand Up @@ -949,7 +948,7 @@ describe("actions", () => {
// Assert.
expect(listener).toHaveBeenCalledTimes(1);
expect(listener).toHaveBeenCalledWith<[PropertyInspectorDidAppearEvent<Settings>]>({
action: actionStore.getActionById(ev.context) as KeyAction,
action: actionStore.getActionById(ev.context) as KeyAction<JsonObject>,
type: "propertyInspectorDidAppear",
});
});
Expand Down Expand Up @@ -979,7 +978,7 @@ describe("actions", () => {
// Assert.
expect(listener).toHaveBeenCalledTimes(1);
expect(listener).toHaveBeenCalledWith<[PropertyInspectorDidDisappearEvent<Settings>]>({
action: actionStore.getActionById(ev.context) as KeyAction,
action: actionStore.getActionById(ev.context) as KeyAction<JsonObject>,
type: "propertyInspectorDidDisappear",
});
});
Expand Down Expand Up @@ -1030,7 +1029,7 @@ describe("actions", () => {
// Assert.
expect(listener).toHaveBeenCalledTimes(1);
expect(listener).toHaveBeenCalledWith<[TitleParametersDidChangeEvent<Settings>]>({
action: actionStore.getActionById(ev.context) as KeyAction,
action: actionStore.getActionById(ev.context) as KeyAction<JsonObject>,
payload: ev.payload,
type: "titleParametersDidChange",
});
Expand Down Expand Up @@ -1074,7 +1073,7 @@ describe("actions", () => {
// Assert.
expect(listener).toHaveBeenCalledTimes(1);
expect(listener).toHaveBeenCalledWith<[TouchTapEvent<Settings>]>({
action: actionStore.getActionById(ev.context) as DialAction,
action: actionStore.getActionById(ev.context) as DialAction<JsonObject>,
payload: ev.payload,
type: "touchTap",
});
Expand Down Expand Up @@ -1117,7 +1116,7 @@ describe("actions", () => {
// Assert.
expect(listener).toHaveBeenCalledTimes(1);
expect(listener).toHaveBeenCalledWith<[WillAppearEvent<Settings>]>({
action: actionStore.getActionById(ev.context) as KeyAction,
action: actionStore.getActionById(ev.context) as KeyAction<JsonObject>,
payload: ev.payload,
type: "willAppear",
});
Expand Down
4 changes: 2 additions & 2 deletions packages/plugin/src/plugin/actions/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const REQUEST_TIMEOUT = 15 * 1000; // 15s
* Provides a contextualized instance of an {@link Action}, allowing for direct communication with the Stream Deck.
* @template T The type of settings associated with the action.
*/
export class Action<T extends JsonObject = JsonObject> extends ActionContext {
export class Action<T extends JsonObject> extends ActionContext {
Comment thread
GeekyEggo marked this conversation as resolved.
Outdated
/**
* Gets the resources (files) associated with this action; these resources are embedded into the
* action when it is exported, either individually, or as part of a profile.
Expand Down Expand Up @@ -108,7 +108,7 @@ export class Action<T extends JsonObject = JsonObject> extends ActionContext {
* @param value Settings to persist.
* @returns `Promise` resolved when the settings are sent to Stream Deck.
*/
public setSettings<U extends JsonObject = T>(value: U): Promise<void> {
public setSettings(value: T): Promise<void> {
Comment thread
GeekyEggo marked this conversation as resolved.
Outdated
settingsCache.delete(this.id);
return connection.send({
event: "setSettings",
Expand Down
2 changes: 1 addition & 1 deletion packages/plugin/src/plugin/actions/dial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { Action } from "./action.js";
* Provides a contextualized instance of a dial action.
* @template T The type of settings associated with the action.
*/
export class DialAction<T extends JsonObject = JsonObject> extends Action<T> {
export class DialAction<T extends JsonObject> extends Action<T> {
Comment thread
GeekyEggo marked this conversation as resolved.
Outdated
/**
* Private backing field for {@link DialAction.coordinates}.
*/
Expand Down
2 changes: 1 addition & 1 deletion packages/plugin/src/plugin/actions/key.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { Action } from "./action.js";
* Provides a contextualized instance of a key action.
* @template T The type of settings associated with the action.
*/
export class KeyAction<T extends JsonObject = JsonObject> extends Action<T> {
export class KeyAction<T extends JsonObject> extends Action<T> {
Comment thread
GeekyEggo marked this conversation as resolved.
Outdated
/**
* Private backing field for {@link KeyAction.coordinates}.
*/
Expand Down
10 changes: 5 additions & 5 deletions packages/plugin/src/plugin/actions/store.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { Enumerable } from "@elgato/utils";
import { Enumerable, type JsonObject } from "@elgato/utils";

import type { DialAction } from "./dial.js";
import type { KeyAction } from "./key.js";

const __items = new Map<string, DialAction | KeyAction>();
const __items = new Map<string, DialAction<JsonObject> | KeyAction<JsonObject>>();

/**
* Provides a read-only store of Stream Deck devices.
*/
export class ReadOnlyActionStore extends Enumerable<DialAction | KeyAction> {
export class ReadOnlyActionStore extends Enumerable<DialAction<JsonObject> | KeyAction<JsonObject>> {
Comment thread
GeekyEggo marked this conversation as resolved.
Outdated
/**
* Initializes a new instance of the {@link ReadOnlyActionStore}.
*/
Expand All @@ -21,7 +21,7 @@ export class ReadOnlyActionStore extends Enumerable<DialAction | KeyAction> {
* @param id Identifier of action to search for.
* @returns The action, when present; otherwise `undefined`.
*/
public getActionById(id: string): DialAction | KeyAction | undefined {
public getActionById(id: string): DialAction<JsonObject> | KeyAction<JsonObject> | undefined {
return __items.get(id);
}
}
Expand All @@ -42,7 +42,7 @@ class ActionStore extends ReadOnlyActionStore {
* Adds the action to the store.
* @param action The action.
*/
public set(action: DialAction | KeyAction): void {
public set(action: DialAction<JsonObject> | KeyAction<JsonObject>): void {
__items.set(action.id, action);
}
}
Expand Down
4 changes: 3 additions & 1 deletion packages/plugin/src/plugin/devices/device.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { JsonObject } from "@elgato/utils";

import type { DeviceInfo, DeviceType, Size } from "../../api/index.js";
import type { DialAction } from "../actions/dial.js";
import type { KeyAction } from "../actions/key.js";
Expand Down Expand Up @@ -61,7 +63,7 @@ export class Device {
* Actions currently visible on the device.
* @returns Collection of visible actions.
*/
public get actions(): IterableIterator<DialAction | KeyAction> {
public get actions(): IterableIterator<DialAction<JsonObject> | KeyAction<JsonObject>> {
return actionStore.filter((a) => a.device.id === this.id);
}

Expand Down
6 changes: 3 additions & 3 deletions packages/plugin/src/plugin/ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class UIController {
/**
* Action associated with the current property inspector.
*/
#action: DialAction | KeyAction | undefined;
#action: DialAction<JsonObject> | KeyAction<JsonObject> | undefined;

/**
* To overcome event races, the debounce counter keeps track of appear vs disappear events, ensuring
Expand Down Expand Up @@ -54,7 +54,7 @@ class UIController {
* Gets the action associated with the current property.
* @returns The action; otherwise `undefined` when a property inspector is not visible.
*/
public get action(): DialAction | KeyAction | undefined {
public get action(): DialAction<JsonObject> | KeyAction<JsonObject> | undefined {
return this.#action;
}

Expand Down Expand Up @@ -134,7 +134,7 @@ class UIController {
* @param action Action to check against.
* @returns `true` when the actions are the same.
*/
#isCurrent(action: DialAction | KeyAction): boolean {
#isCurrent(action: DialAction<JsonObject> | KeyAction<JsonObject>): boolean {
return (
this.#action?.id === action.id &&
this.#action?.manifestId === action.manifestId &&
Expand Down
Loading