diff --git a/src/tests/webR/webr-main.test.ts b/src/tests/webR/webr-main.test.ts index 5e737208..8e22d3f7 100644 --- a/src/tests/webR/webr-main.test.ts +++ b/src/tests/webR/webr-main.test.ts @@ -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'); }); @@ -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!'); diff --git a/src/webR/proxy.ts b/src/webR/proxy.ts index cbd9ab99..06787d68 100644 --- a/src/webR/proxy.ts +++ b/src/webR/proxy.ts @@ -43,15 +43,19 @@ export type DistProxy = U extends RWorker.RObject ? RProxy : U; * converted to a corresponding type using `RProxify` recursively. * @typeParam T The type to convert. */ -export type RProxify = T extends Array +export type RProxify = T extends Array // [RObject, RObject, ...] ? Promise[]> - : T extends (...args: infer U) => any + : T extends (...args: infer U) => any // (...args) => ? ( ...args: { [V in keyof U]: DistProxy; } ) => RProxify> - : Promise>; + : T extends { result: RWorker.RObject, output: RWorker.RObject } // Return type of .capture() + ? Promise<{ + [U in keyof T]: DistProxy + }> + : Promise>; // RObject, any other types /** * Create an {@link RProxy} based on an {@link RWorker.RObject} type parameter. diff --git a/src/webR/webr-main.ts b/src/webR/webr-main.ts index 392f0603..e547d27c 100644 --- a/src/webR/webr-main.ts +++ b/src/webR/webr-main.ts @@ -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);