Skip to content

Commit

Permalink
Fix typing in result of RCall.capture()
Browse files Browse the repository at this point in the history
  • Loading branch information
georgestagg committed Feb 16, 2024
1 parent 86cddda commit cfeb1d8
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 15 deletions.
17 changes: 9 additions & 8 deletions src/tests/webR/webr-main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,9 @@ describe('Evaluate R code', () => {

test('Error conditions are re-thrown in JS when executing an R function', async () => {
const fn = await webR.evalR('sin') as RFunction;
let throws = fn("abc");
let throws = fn('abc');
await expect(throws).rejects.toThrow('non-numeric argument to mathematical function');
throws = fn.exec("abc");
throws = fn.exec('abc');
await expect(throws).rejects.toThrow('non-numeric argument to mathematical function');
});

Expand Down Expand Up @@ -166,18 +166,19 @@ describe('Evaluate R code', () => {
captureConditions: true,
});

let outType = await result.output.pluck(1, 'type')!;
let outData = await result.output.pluck(1, 'data')!;
let outType = await result.output.pluck(1, 'type') as RCharacter;
let outData = await result.output.pluck(1, 'data') as RCharacter;

expect(await outType.toString()).toEqual('stdout');
expect(await outData.toString()).toContain('Hello, stdout!');

outType = await result.output.pluck(2, 'type')!;
outData = await result.output.pluck(2, 'data', 'message')!;
outType = await result.output.pluck(2, 'type') as RCharacter;
outData = await result.output.pluck(2, 'data', 'message') as RCharacter;
expect(await outType.toString()).toEqual('message');
expect(await outData.toString()).toContain('Hello, message!');

outType = await result.output.pluck(3, 'type')!;
outData = await result.output.pluck(3, 'data', 'message')!;
outType = await result.output.pluck(3, 'type') as RCharacter;
outData = await result.output.pluck(3, 'data', 'message') as RCharacter;
expect(await outType.toString()).toEqual('warning');
expect(await outData.toString()).toContain('Hello, warning!');

Expand Down
10 changes: 7 additions & 3 deletions src/webR/proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,19 @@ export type DistProxy<U> = U extends RWorker.RObject ? RProxy<U> : U;
* converted to a corresponding type using `RProxify` recursively.
* @typeParam T The type to convert.
*/
export type RProxify<T> = T extends Array<any>
export type RProxify<T> = T extends Array<any> // [RObject, RObject, ...]
? Promise<DistProxy<T[0]>[]>
: T extends (...args: infer U) => any
: T extends (...args: infer U) => any // (...args) => <RObject>
? (
...args: {
[V in keyof U]: DistProxy<U[V]>;
}
) => RProxify<ReturnType<T>>
: Promise<DistProxy<T>>;
: T extends { result: RWorker.RObject, output: RWorker.RObject } // Return type of .capture()
? Promise<{
[U in keyof T]: DistProxy<T[U]>
}>
: Promise<DistProxy<T>>; // RObject, any other types

/**
* Create an {@link RProxy} based on an {@link RWorker.RObject} type parameter.
Expand Down
12 changes: 8 additions & 4 deletions src/webR/webr-main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -599,17 +599,21 @@ export class Shelter {
/**
* Evaluate the given R code, capturing output.
*
* Stream outputs and conditions raised during exectution are captured and
* Stream outputs and conditions raised during execution are captured and
* returned as part of the output of this function. Returned R objects are
* protected by the shelter.
* @param {string} code The R code to evaluate.
* @param {EvalROptions} [options] Options for the execution environment.
* @returns {Promise<{result: RObject, output: unknown[]}>} An object
* containing the result of the computation and and array of captured output.
* @returns {Promise<{
* result: RObject,
* output: { type: string; data: any }[],
* images: ImageBitmap[]
* }>} An object containing the result of the computation, an array of output,
* and an array of captured plots.
*/
async captureR(code: string, options: EvalROptions = {}): Promise<{
result: RObject;
output: unknown[];
output: { type: string; data: any }[];
images: ImageBitmap[];
}> {
const opts = replaceInObject(options, isRObject, (obj: RObject) => obj._payload);
Expand Down

0 comments on commit cfeb1d8

Please sign in to comment.