Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow for outputVariables and inputVariables in RequestBatchRequest type. #313

Open
FiniteSingularity opened this issue Nov 19, 2022 · 2 comments

Comments

@FiniteSingularity
Copy link

Description:

One of the many significant changes to the OBS websocket v5 protocol is that source visibility requires the source's ID within the scene where it is being enabled/disabled. For something as simple (and common) as toggling on/off a source, this is cumbersome and can add considerable complexity to client code. The "recommended" way of doing this is to use a batched request that get's a source's id within a scene (given the scene name and source name), store its value in the outputVariables field of that request, then send a source enable request that specifies an inputVariable from the prior request's outputVariables as the sourceId. (An example is given in the issue here: obsproject/obs-websocket#1014 (comment) ). Unfortunately, the typescript typedef for RequestBatchRequest does not allow for the inputVariables or outputVariables fields.

Modifying the type.d.ts file to allow for an optional inputVariables: any and outputVariables: any allows this to work via obs-websocket-js. However it appears that this file is automatically generated from OBS Websocket's types?

Versions Used (if applicable):

  • obs-websocket-js version: 5.0.2
  • obs-studio version: 28.1.2
@FiniteSingularity
Copy link
Author

I just started putting together a PR that adds a properly typed outputVariables and a semi-typed inputVariables to the RequestBatchRequest type. I'll work a bit on the inputVariables and submit a PR soon, but if folks want to give it a try, you can find the branch here: https://github.com/FiniteSingularity/obs-websocket-js/tree/feature/adds-input-output-vars

@FiniteSingularity
Copy link
Author

FiniteSingularity commented Nov 22, 2022

One issue I am seeing is that of enforcing type safety. About the best option I can come up with is this:

export declare type RequestBatchRequest<T = keyof OBSRequestTypes> = T extends keyof OBSRequestTypes ? OBSRequestTypes[T] extends never ? {
    requestType: T;
    requestId?: string;
    outputVariables?: Record<string, keyof OBSResponseTypes[T]>;
} : {
    requestType: T;
    requestId?: string;
    requestData: Partial<OBSRequestTypes[T]>;
    inputVariables?: Partial<OBSRequestTypes[T]>;
    outputVariables?: Record<string, keyof OBSResponseTypes[T]>;
} : never;

requestData to must be a Partial<OBSRequestTypes[T]> because the keys we replace using inputVariables will no longer exist in requestData. What we really need is for the union of requestData and the optional inputVariables to be an OBSRequestTypes[T]. I've tried (unsuccessfully) to do this in a few ways, for example, letting inputVariables be a Record<string, string>, then using Omit on those keys for requestData:

export declare type RequestBatchRequest<T = keyof OBSRequestTypes, S = Record<string, string>> = T extends keyof OBSRequestTypes ? OBSRequestTypes[T] extends never ? {
    requestType: T;
    requestId?: string;
    outputVariables?: Record<string, keyof OBSResponseTypes[T]>;
} : {
    requestType: T;
    requestId?: string;
    requestData: Omit<OBSRequestTypes[T], keyof S>;
    inputVariables?: S;
    outputVariables?: Record<string, keyof OBSResponseTypes[T]>;
} : never;

However, unless the template for S is explicitly set when implementing a RequestBatchRequest, the Omit on requestData sees S as never, and type checking is lost. e.g.- in order for this to work, one would have to do something like:

const req: RequestBatchRequest<'someRequest', {fieldName: string}> = {
  requestType: 'someRequest',
  requestData: { aField: 'value' },
  inputVariables: {fieldName: 'outputVariableName'},
}

If anyone has other ideas, I am all ears.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant