first commit

This commit is contained in:
Andreas Gammelgaard Damsbo 2024-01-11 09:43:23 +01:00
commit 6333bcee61
208 changed files with 413695 additions and 0 deletions

View file

@ -0,0 +1,21 @@
import { SharedBufferChannelMain, SharedBufferChannelWorker } from './channel-shared';
import { ServiceWorkerChannelMain, ServiceWorkerChannelWorker } from './channel-service';
import { PostMessageChannelMain, PostMessageChannelWorker } from './channel-postmessage';
import { WebROptions } from '../webr-main';
export declare const ChannelType: {
readonly Automatic: 0;
readonly SharedArrayBuffer: 1;
readonly ServiceWorker: 2;
readonly PostMessage: 3;
};
export type ChannelInitMessage = {
type: string;
data: {
config: Required<WebROptions>;
channelType: Exclude<(typeof ChannelType)[keyof typeof ChannelType], typeof ChannelType.Automatic>;
clientId?: string;
location?: string;
};
};
export declare function newChannelMain(data: Required<WebROptions>): SharedBufferChannelMain | ServiceWorkerChannelMain | PostMessageChannelMain;
export declare function newChannelWorker(msg: ChannelInitMessage): SharedBufferChannelWorker | ServiceWorkerChannelWorker | PostMessageChannelWorker;

View file

@ -0,0 +1,26 @@
import { Message } from './message';
import { WebROptions } from '../webr-main';
import { ChannelMain } from './channel';
export declare class PostMessageChannelMain extends ChannelMain {
#private;
initialised: Promise<unknown>;
resolve: (_?: unknown) => void;
close: () => void;
constructor(config: Required<WebROptions>);
interrupt(): void;
}
export declare class PostMessageChannelWorker {
#private;
constructor();
resolve(): void;
write(msg: Message, transfer?: [Transferable]): void;
writeSystem(msg: Message, transfer?: [Transferable]): void;
read(): Message;
inputOrDispatch(): number;
run(_args: string[]): void;
setDispatchHandler(dispatch: (msg: Message) => void): void;
request(msg: Message, transferables?: [Transferable]): Promise<any>;
setInterrupt(_: () => void): void;
handleInterrupt(): void;
onMessageFromMainThread(message: Message): void;
}

View file

@ -0,0 +1,30 @@
import { Message, Response } from './message';
import { ChannelMain, ChannelWorker } from './channel';
import { WebROptions } from '../webr-main';
export declare class ServiceWorkerChannelMain extends ChannelMain {
#private;
initialised: Promise<unknown>;
resolve: (_?: unknown) => void;
close: () => void;
constructor(config: Required<WebROptions>);
activeRegistration(): ServiceWorker;
interrupt(): void;
}
export declare class ServiceWorkerChannelWorker implements ChannelWorker {
#private;
onMessageFromMainThread: (msg: Message) => void;
constructor(data: {
clientId?: string;
location?: string;
});
resolve(): void;
write(msg: Message, transfer?: [Transferable]): void;
writeSystem(msg: Message, transfer?: [Transferable]): void;
syncRequest(message: Message): Response;
read(): Message;
inputOrDispatch(): number;
run(args: string[]): void;
setInterrupt(interrupt: () => void): void;
handleInterrupt(): void;
setDispatchHandler(dispatch: (msg: Message) => void): void;
}

View file

@ -0,0 +1,25 @@
import { Message } from './message';
import { ChannelMain, ChannelWorker } from './channel';
import { WebROptions } from '../webr-main';
export declare class SharedBufferChannelMain extends ChannelMain {
#private;
initialised: Promise<unknown>;
resolve: (_?: unknown) => void;
close: () => void;
constructor(config: Required<WebROptions>);
interrupt(): void;
}
export declare class SharedBufferChannelWorker implements ChannelWorker {
#private;
onMessageFromMainThread: (msg: Message) => void;
constructor();
resolve(): void;
write(msg: Message, transfer?: [Transferable]): void;
writeSystem(msg: Message, transfer?: [Transferable]): void;
read(): Message;
inputOrDispatch(): number;
run(args: string[]): void;
setInterrupt(interrupt: () => void): void;
handleInterrupt(): void;
setDispatchHandler(dispatch: (msg: Message) => void): void;
}

View file

@ -0,0 +1,44 @@
/**
* Interfaces for the webR main and worker thread communication channels.
* @module Channel
*/
import { AsyncQueue } from './queue';
import { Message, Response } from './message';
import { WebRPayload } from '../payload';
export declare abstract class ChannelMain {
#private;
inputQueue: AsyncQueue<Message>;
outputQueue: AsyncQueue<Message>;
systemQueue: AsyncQueue<Message>;
abstract initialised: Promise<unknown>;
abstract close(): void;
abstract interrupt(): void;
read(): Promise<Message>;
flush(): Promise<Message[]>;
readSystem(): Promise<Message>;
write(msg: Message): void;
request(msg: Message, transferables?: [Transferable]): Promise<WebRPayload>;
protected putClosedMessage(): void;
protected resolveResponse(msg: Response): void;
}
export interface ChannelWorker {
resolve(): void;
write(msg: Message, transfer?: [Transferable]): void;
writeSystem(msg: Message, transfer?: [Transferable]): void;
read(): Message;
handleInterrupt(): void;
setInterrupt(interrupt: () => void): void;
run(args: string[]): void;
inputOrDispatch: () => number;
setDispatchHandler: (dispatch: (msg: Message) => void) => void;
onMessageFromMainThread: (msg: Message) => void;
}
/**
* Handler functions dealing with setup and commmunication over a Service Worker.
*/
export interface ServiceWorkerHandlers {
handleActivate: (this: ServiceWorkerGlobalScope, ev: ExtendableEvent) => any;
handleFetch: (this: ServiceWorkerGlobalScope, ev: FetchEvent) => any;
handleInstall: (this: ServiceWorkerGlobalScope, ev: ExtendableEvent) => any;
handleMessage: (this: ServiceWorkerGlobalScope, ev: ExtendableMessageEvent) => any;
}

View file

@ -0,0 +1,50 @@
/**
* WebR communication channel messaging and request types.
* @module Message
*/
import { UUID } from './task-common';
/** A webR communication channel message. */
export interface Message {
type: string;
data?: any;
}
/** A webR communication channel request. */
export interface Request {
type: 'request';
data: {
uuid: UUID;
msg: Message;
};
}
/** A webR communication channel response. */
export interface Response {
type: 'response';
data: {
uuid: UUID;
resp: unknown;
};
}
/** @internal */
export declare function newRequest(msg: Message, transferables?: [Transferable]): Request;
/** @internal */
export declare function newResponse(uuid: UUID, resp: unknown, transferables?: [Transferable]): Response;
/** A webR communication channel sync-request.
* @internal
*/
export interface SyncRequest {
type: 'sync-request';
data: {
msg: Message;
reqData: SyncRequestData;
};
}
/** Transfer data required when using sync-request with SharedArrayBuffer.
* @internal */
export interface SyncRequestData {
taskId?: number;
sizeBuffer: Int32Array;
signalBuffer: Int32Array;
dataBuffer: Uint8Array;
}
/** @internal */
export declare function newSyncRequest(msg: Message, data: SyncRequestData): SyncRequest;

View file

@ -0,0 +1,17 @@
/**
* @module Queue
*/
/**
* Asynchronous queue mechanism to be used by the communication channels.
* @typeParam T The type of item to be stored in the queue.
*/
export declare class AsyncQueue<T> {
#private;
constructor();
reset(): void;
put(t: T): void;
get(): Promise<T>;
isEmpty(): boolean;
isBlocked(): boolean;
get length(): number;
}

View file

@ -0,0 +1,6 @@
import { ServiceWorkerHandlers } from './channel';
export declare function handleInstall(): void;
export declare function handleActivate(event: ExtendableEvent): void;
export declare function handleFetch(event: FetchEvent): boolean;
export declare function handleMessage(event: ExtendableMessageEvent): boolean;
export declare const webRHandlers: ServiceWorkerHandlers;

View file

@ -0,0 +1,17 @@
export declare const SZ_BUF_DOESNT_FIT = 0;
export declare const SZ_BUF_FITS_IDX = 1;
export declare const SZ_BUF_SIZE_IDX = 0;
export interface Endpoint extends EventSource {
postMessage(message: any, transfer?: Transferable[]): void;
start?: () => void;
}
export interface EventSource {
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: {}): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: {}): void;
}
export declare function toWireValue(value: any): [any, Transferable[]];
export declare function transfer<T>(obj: T, transfers: Transferable[]): T;
export type UUID = string;
export declare function isUUID(x: any): x is UUID;
export declare const UUID_LENGTH = 63;
export declare function generateUUID(): UUID;

View file

@ -0,0 +1,15 @@
import { Endpoint } from './task-common';
import { SyncRequestData } from './message';
/**
* Respond to a blocking request. Most of the work has already been done in
* asynclink, we are just responsible here for getting the return value back to
* the requester through this slightly convoluted Atomics protocol.
* @param {Endpoint} endpoint A message port to receive messages from. Other
* thread is blocked, so we can't send messages back.
* @param {SyncRequestData} data The message that was recieved. We will use it
* to read out the buffers to write the answer into. NOTE: requester
* owns buffers.
* @param {any} response The value we want to send back to the requester. We
* have to encode it into data_buffer.
*/
export declare function syncResponse(endpoint: Endpoint, data: SyncRequestData, response: any): Promise<void>;

View file

@ -0,0 +1,42 @@
import { Endpoint } from './task-common';
import { Message } from './message';
export declare class SyncTask {
#private;
endpoint: Endpoint;
msg: Message;
transfers: Transferable[];
taskId?: number;
sizeBuffer?: Int32Array;
signalBuffer?: Int32Array;
syncifier: _Syncifier;
constructor(endpoint: Endpoint, msg: Message, transfers?: Transferable[]);
scheduleSync(): this | undefined;
poll(): boolean;
doSync(): Generator<undefined, unknown, unknown>;
get result(): unknown;
syncify(): any;
}
declare class _Syncifier {
nextTaskId: Int32Array;
signalBuffer: Int32Array;
tasks: Map<number, SyncTask>;
constructor();
scheduleTask(task: SyncTask): void;
waitOnSignalBuffer(): void;
tasksIdsToWakeup(): Generator<number, void, unknown>;
pollTasks(task?: SyncTask): boolean;
syncifyTask(task: SyncTask): void;
}
/**
* Sets the interrupt handler. This is called when the computation is
* interrupted. Should zero the interrupt buffer and throw an exception.
* @internal
*/
export declare function setInterruptHandler(handler: () => void): void;
/**
* Sets the interrupt buffer. Should be a shared array buffer. When element 0
* is set non-zero it signals an interrupt.
* @internal
*/
export declare function setInterruptBuffer(buffer: ArrayBufferLike): void;
export {};

2
docs/shinylive/webr/webR/compat.d.ts vendored Normal file
View file

@ -0,0 +1,2 @@
export declare const IN_NODE: boolean;
export declare let loadScript: (url: string) => Promise<void>;

2
docs/shinylive/webr/webR/config.d.ts vendored Normal file
View file

@ -0,0 +1,2 @@
export declare const BASE_URL: string;
export declare const PKG_BASE_URL = "https://repo.r-wasm.org";

72
docs/shinylive/webr/webR/console.d.ts vendored Normal file
View file

@ -0,0 +1,72 @@
import { WebR, WebROptions } from './webr-main';
export interface ConsoleCallbacks {
stdout?: (line: string) => void;
stderr?: (line: string) => void;
prompt?: (line: string) => void;
canvasImage?: (image: ImageBitmap) => void;
canvasNewPage?: () => void;
}
/**
* Text-based Interactive Console for WebR
*
* A helper application to assist in creating an interactive R REPL based on
* JavaScript callbacks.
*
* Callback functions ``stdout`` and ``stderr`` are called with a single line
* of output as the first argument. The default implementation of `stdout` and
* `stderr` writes to the console using `console.log` and `console.error`.
*
* R code can be sent as input by calling the ``stdin`` method with a single
* line of textual input.
*
* A long running R computation can be interrupted by calling the `interrupt`
* method.
*
* The ``prompt`` callback function is called when webR produces a prompt at
* the REPL console and is therefore awaiting user input. The prompt character
* (usually ``>`` or ``+``) is given as the first argument to the callback
* function. The default implementation of `prompt` shows a JavaScript prompt
* asking the user for input, and then sends the user input to `stdin`.
*
* The ``canvasImage`` callback function is called when webR writes plots to
* the built-in HTML canvas graphics device.
*
* The ``canvasNewPage`` callback function is called when webR creates a new
* plot.
*
* Once constructed, start the Console using the ``run`` method. The `run`
* method starts an asynchronous infinite loop that waits for output from the
* webR worker and then calls the relevant callbacks.
*/
export declare class Console {
#private;
/** The supporting instance of webR */
webR: WebR;
/**
* A HTML canvas element
*
* The canvas graphics device writes to this element by default. Undefined
* when HTML canvas is unsupported.
*/
canvas: HTMLCanvasElement | undefined;
/**
* @param {ConsoleCallbacks} callbacks A list of webR Console callbacks to
* be used for this console.
* @param {WebROptions} options The options to use for the new instance of
* webR started to support this console.
*/
constructor(callbacks?: ConsoleCallbacks, options?: WebROptions);
/**
* Write a line of input to webR's REPL through ``stdin``
* @param {string} input A line of input text.
*/
stdin(input: string): void;
/**
* Interrupt a long running R computation and return to the prompt
*/
interrupt(): void;
/**
* Start the webR console
*/
run(): void;
}

138
docs/shinylive/webr/webR/emscripten.d.ts vendored Normal file
View file

@ -0,0 +1,138 @@
/// <reference types="emscripten" />
import type { RPtr, RTypeNumber } from './robj';
import type { UnwindProtectException } from './utils-r';
export interface Module extends EmscriptenModule {
FS: typeof FS & {
mkdirTree(path: string): void;
filesystems: {
[key: string]: Emscripten.FileSystemType;
};
};
ENV: {
[key: string]: string;
};
GOT: {
[key: string]: {
required: boolean;
value: number;
};
};
createLazyFilesystem: () => void;
monitorRunDependencies: (n: number) => void;
noImageDecoding: boolean;
noAudioDecoding: boolean;
noWasmDecoding: boolean;
setPrompt: (prompt: string) => void;
canvasExec: (op: string) => void;
downloadFileContent: (URL: string, headers: Array<string>) => {
status: number;
response: string | ArrayBuffer;
};
mountImageUrl: (url: string, mountpoint: string) => void;
mountImagePath: (path: string, mountpoint: string) => void;
allocateUTF8: typeof allocateUTF8;
allocateUTF8OnStack: typeof allocateUTF8OnStack;
getValue: typeof getValue;
setValue: typeof setValue;
UTF8ToString: typeof UTF8ToString;
callMain: (args: string[]) => void;
getWasmTableEntry: (entry: number) => Function;
_ATTRIB: (ptr: RPtr) => RPtr;
_CAR: (ptr: RPtr) => RPtr;
_CDR: (ptr: RPtr) => RPtr;
_CLOENV: (ptr: RPtr) => RPtr;
_COMPLEX: (ptr: RPtr) => RPtr;
_FRAME: (ptr: RPtr) => RPtr;
_INTEGER: (ptr: RPtr) => RPtr;
_INTERNAL: (ptr: RPtr) => RPtr;
_LENGTH: (ptr: RPtr) => number;
_LOGICAL: (ptr: RPtr) => RPtr;
_PRINTNAME: (ptr: RPtr) => RPtr;
_R_CHAR: (ptr: RPtr) => RPtr;
_RAW: (ptr: RPtr) => RPtr;
_REAL: (ptr: RPtr) => RPtr;
_SETCAR: (x: RPtr, y: RPtr) => void;
_STRING_ELT: (ptr: RPtr, idx: number) => RPtr;
_STRING_PTR: (ptr: RPtr) => RPtr;
_SYMVALUE: (ptr: RPtr) => RPtr;
_TAG: (ptr: RPtr) => RPtr;
_TYPEOF: (ptr: RPtr) => RPtr;
_VECTOR_ELT: (ptr: RPtr, idx: number) => RPtr;
_R_lsInternal3: (env: RPtr, all: number, sorted: number) => RPtr;
_R_MakeExternalPtr: (p: number, tag: RPtr, prot: RPtr) => RPtr;
_R_NewEnv: (enclos: RPtr, hash: number, size: number) => RPtr;
_R_ParseEvalString: (code: number, env: RPtr) => RPtr;
_R_PreserveObject: (ptr: RPtr) => void;
_R_ReleaseObject: (ptr: RPtr) => void;
_R_ReplDLLinit: () => void;
_R_ReplDLLdo1: () => number;
_Rf_ScalarReal: (n: number) => RPtr;
_Rf_ScalarLogical: (l: number) => RPtr;
_Rf_ScalarInteger: (n: number) => RPtr;
_Rf_ScalarString: (s: string) => RPtr;
_Rf_allocList: (len: number) => RPtr;
_Rf_allocVector: (type: RTypeNumber, len: number) => RPtr;
_Rf_defineVar: (symbol: RPtr, value: RPtr, env: RPtr) => void;
_Rf_error: (msg: EmPtr) => void;
_Rf_eval: (call: RPtr, env: RPtr) => RPtr;
_Rf_findVarInFrame: (rho: RPtr, symbol: RPtr) => RPtr;
_Rf_listAppend: (source: RPtr, target: RPtr) => RPtr;
_Rf_getAttrib: (ptr1: RPtr, ptr2: RPtr) => RPtr;
_Rf_initialize_R: (argc: number, argv: RPtr) => void;
_Rf_install: (ptr: number) => RPtr;
_Rf_installTrChar: (name: RPtr) => RPtr;
_Rf_lang1: (ptr1: RPtr) => RPtr;
_Rf_lang2: (ptr1: RPtr, ptr2: RPtr) => RPtr;
_Rf_lang3: (ptr1: RPtr, ptr2: RPtr, ptr3: RPtr) => RPtr;
_Rf_lang4: (ptr1: RPtr, ptr2: RPtr, ptr3: RPtr, ptr4: RPtr) => RPtr;
_Rf_lang5: (ptr1: RPtr, ptr2: RPtr, ptr3: RPtr, ptr4: RPtr, ptr5: RPtr) => RPtr;
_Rf_lang6: (ptr1: RPtr, ptr2: RPtr, ptr3: RPtr, ptr4: RPtr, ptr5: RPtr, ptr6: RPtr) => RPtr;
_Rf_mkChar: (ptr: number) => RPtr;
_Rf_mkString: (ptr: number) => RPtr;
_Rf_onintr: () => void;
_Rf_protect: (ptr: RPtr) => RPtr;
_R_ContinueUnwind: (cont: RPtr) => never;
_R_ProtectWithIndex: (ptr1: RPtr, ptr2: RPtr) => void;
_R_Reprotect: (ptr1: RPtr, ptr2: RPtr) => void;
_Rf_setAttrib: (ptr1: RPtr, ptr2: RPtr, ptr3: RPtr) => RPtr;
_Rf_unprotect: (n: number) => void;
_Rf_unprotect_ptr: (ptr: RPtr) => void;
_DLLbuf: RPtr;
_DLLbufp: RPtr;
_R_BaseEnv: RPtr;
_R_BracketSymbol: RPtr;
_R_Bracket2Symbol: RPtr;
_R_DollarSymbol: RPtr;
_R_EmptyEnv: RPtr;
_R_FalseValue: RPtr;
_R_GlobalEnv: RPtr;
_R_Interactive: RPtr;
_R_NaInt: RPtr;
_R_NaReal: RPtr;
_R_NaString: RPtr;
_R_LogicalNAValue: RPtr;
_R_NilValue: RPtr;
_R_TrueValue: RPtr;
_R_NamesSymbol: RPtr;
_R_UnboundValue: RPtr;
_SET_STRING_ELT: (ptr: RPtr, idx: number, val: RPtr) => void;
_SET_VECTOR_ELT: (ptr: RPtr, idx: number, val: RPtr) => void;
_setup_Rmainloop: () => void;
_strcpy: (dest: RPtr, src: RPtr) => number;
webr: {
UnwindProtectException: typeof UnwindProtectException;
readConsole: () => number;
resolveInit: () => void;
handleEvents: () => void;
evalJs: (code: RPtr) => number;
setTimeoutWasm: (ptr: EmPtr, data: EmPtr, delay: number) => void;
};
}
export declare const Module: Module;
export type EmPtr = ReturnType<typeof Module.allocateUTF8>;
export interface DictEmPtrs {
[key: string]: EmPtr;
}
export declare function dictEmFree(dict: {
[key: string | number]: EmPtr;
}): void;

26
docs/shinylive/webr/webR/error.d.ts vendored Normal file
View file

@ -0,0 +1,26 @@
/**
* Custom Error classes that shall be raised by webR.
* @module Error
*/
/**
* A general error raised by webR.
*/
export declare class WebRError extends Error {
constructor(msg: string);
}
/**
* Exceptions raised on the webR worker thread that have been forwarded to the
* main thread through the communication channel.
*/
export declare class WebRWorkerError extends WebRError {
}
/**
* Exceptions related to issues with the webR communication channel.
*/
export declare class WebRChannelError extends WebRError {
}
/**
* Exceptions related to issues with webR object payloads.
*/
export declare class WebRPayloadError extends WebRError {
}

47
docs/shinylive/webr/webR/payload.d.ts vendored Normal file
View file

@ -0,0 +1,47 @@
/**
* Types containing references to R objects, raw data or errors over the webR
* communication channel.
* @module Payload
*/
import { WebRDataRaw, RPtr, RType } from './robj';
export type WebRPayloadRaw = {
obj: WebRDataRaw;
payloadType: 'raw';
};
export type WebRPayloadPtr = {
obj: {
type?: RType;
ptr: RPtr;
methods?: string[];
};
payloadType: 'ptr';
};
export type WebRPayloadErr = {
obj: {
message: string;
name: string;
stack?: string;
};
payloadType: 'err';
};
export type WebRPayload = WebRPayloadRaw | WebRPayloadPtr;
export type WebRPayloadWorker = WebRPayloadRaw | WebRPayloadPtr | WebRPayloadErr;
export declare function webRPayloadAsError(payload: WebRPayloadErr): Error;
/**
* Test for an WebRPayload instance.
* @param {any} value The object to test.
* @returns {boolean} True if the object is an instance of an WebRPayload.
*/
export declare function isWebRPayload(value: any): value is WebRPayload;
/**
* Test for an WebRPayloadPtr instance.
* @param {any} value The object to test.
* @returns {boolean} True if the object is an instance of an WebRPayloadPtr.
*/
export declare function isWebRPayloadPtr(value: any): value is WebRPayloadPtr;
/**
* Test for an WebRPayloadRaw instance.
* @param {any} value The object to test.
* @returns {boolean} True if the object is an instance of an WebRPayloadRaw.
*/
export declare function isWebRPayloadRaw(value: any): value is WebRPayloadRaw;

115
docs/shinylive/webr/webR/proxy.d.ts vendored Normal file
View file

@ -0,0 +1,115 @@
/**
* Proxy R objects on the webR worker thread so that they can be accessed from
* the main thread.
* @module Proxy
*/
import { ChannelMain } from './chan/channel';
import { WebRPayloadPtr } from './payload';
import { RType } from './robj';
import * as RWorker from './robj-worker';
import { ShelterID } from './webr-chan';
/**
* Obtain a union of the keys corresponding to methods of a given class `T`.
* @typeParam T The type to provide the methods for.
*/
export type Methods<T> = {
[P in keyof T]: T[P] extends (...args: any) => any ? P : never;
}[keyof T];
/**
* Distributive conditional type for {@link RProxy}.
*
* Distributes {@link RProxy} over any {@link RWorker.RObject} in the given
* union type U.
* @typeParam U The type union to distribute {@link RProxy} over.
*/
export type DistProxy<U> = U extends RWorker.RObject ? RProxy<U> : U;
/**
* Convert {@link RWorker.RObject} properties for use with an {@link RProxy}.
*
* Properties in the type parameter `T` are mapped so that {@link RProxy} is
* distributed over any {@link RWorker.RObject} types, then wrapped in a
* Promise.
*
* Function signatures are mapped so that arguments with {@link RWorker.RObject}
* type instead take {@link RProxy}<{@link RWorker.RObject}> type. Other
* function arguments remain as they are. The function return type is also
* converted to a corresponding type using `RProxify` recursively.
* @typeParam T The type to convert.
*/
export type RProxify<T> = T extends Array<any> ? Promise<DistProxy<T[0]>[]> : T extends (...args: infer U) => any ? (...args: {
[V in keyof U]: DistProxy<U[V]>;
}) => RProxify<ReturnType<T>> : Promise<DistProxy<T>>;
/**
* Create an {@link RProxy} based on an {@link RWorker.RObject} type parameter.
*
* R objects created via an {@link RProxy} are intended to be used in place of
* {@link RWorker.RObject} on the main thread. An {@link RProxy} object has the
* same instance methods as the given {@link RWorker.RObject} parameter, with
* the following differences:
* * Method arguments take `RProxy` in place of {@link RWorker.RObject}.
*
* * Where an {@link RWorker.RObject} would be returned, an `RProxy` is
* returned instead.
*
* * All return types are wrapped in a Promise.
*
* If required, the {@link Payload.WebRPayloadPtr} object associated with the
* proxy can be accessed directly through the `_payload` property.
* @typeParam T The {@link RWorker.RObject} type to convert into `RProxy` type.
*/
export type RProxy<T extends RWorker.RObject> = {
[P in Methods<T>]: RProxify<T[P]>;
} & {
_payload: WebRPayloadPtr;
[Symbol.asyncIterator](): AsyncGenerator<RProxy<RWorker.RObject>, void, unknown>;
};
/**
* Create a proxy constructor based on a {@link RWorker.RObject} class.
*
* The class constructors and static methods of the given subclass of
* {@link RWorker.RObject} are proxied, and the proxied constructor returns a
* promise to an R object of a given {@link RProxy} type.
* @typeParam T The type of the {@link RWorker.RObject} class to be proxied.
* @typeParam R The type to be returned from the proxied class constructor.
*/
export type ProxyConstructor<T, R> = (T extends abstract new (...args: infer U) => any ? {
new (...args: {
[V in keyof U]: U[V];
}): Promise<R>;
} : never) & {
[P in Methods<typeof RWorker.RObject>]: RProxify<(typeof RWorker.RObject)[P]>;
};
/**
* Proxy an R object method by providing an async function that requests that
* the worker thread calls the method and then returns the result.
*
* When the optional payload argument has not been provided, an
* {@link RWorker.RObject} static method is called.
* @internal
*/
export declare function targetMethod(chan: ChannelMain, prop: string): any;
export declare function targetMethod(chan: ChannelMain, prop: string, payload: WebRPayloadPtr): any;
/**
* Proxy an R object.
*
* The proxy targets a particular R object in WebAssembly memory. Methods of the
* relevant subclass of {@link RWorker.RObject} are proxied, enabling
* structured manipulation of R objects from the main thread.
* @param {ChannelMain} chan The current main thread communication channel.
* @param {WebRPayloadPtr} payload A webR payload referencing an R object.
* @returns {RProxy<RWorker.RObject>} An {@link RObject} corresponding to the
* referenced R object.
*/
export declare function newRProxy(chan: ChannelMain, payload: WebRPayloadPtr): RProxy<RWorker.RObject>;
/**
* Proxy an {@link RWorker.RObject} class.s
* @param {ChannelMain} chan The current main thread communication channel.
* @param {ShelterID} shelter The shelter ID to protect returned objects with.
* @param {(RType | 'object')} objType The R object type, or `'object'` for the
* generic {@link RWorker.RObject} class.
* @returns {ProxyConstructor} A proxy to the R object subclass corresponding to
* the given value of the `objType` argument.
* @typeParam T The type of the {@link RWorker.RObject} class to be proxied.
* @typeParam R The type to be returned from the proxied class constructor.
*/
export declare function newRClassProxy<T, R>(chan: ChannelMain, shelter: ShelterID, objType: RType | 'object'): ProxyConstructor<T, R>;

112
docs/shinylive/webr/webR/robj-main.d.ts vendored Normal file
View file

@ -0,0 +1,112 @@
/**
* Module for working with R objects on the main thead through
* JavaScript proxies. The `RObject` types in `RMain` are aliases for
* proxies to the corresponding types in `RWorker`. For instance,
* `RMain.RCharacter` is an alias for `RMain.RProxy<RWorker.RCharacter>`.
* The proxies automatically and asynchronously forward method and
* getter calls to the implementations on the R worker side.
* @module RMain
*/
import type { RProxy } from './proxy';
import * as RWorker from './robj-worker';
export type RObject = RProxy<RWorker.RObject>;
export type RNull = RProxy<RWorker.RNull>;
export type RSymbol = RProxy<RWorker.RSymbol>;
export type RPairlist = RProxy<RWorker.RPairlist>;
export type REnvironment = RProxy<RWorker.REnvironment>;
export type RString = RProxy<RWorker.RString>;
export type RLogical = RProxy<RWorker.RLogical>;
export type RInteger = RProxy<RWorker.RInteger>;
export type RDouble = RProxy<RWorker.RDouble>;
export type RComplex = RProxy<RWorker.RComplex>;
export type RCharacter = RProxy<RWorker.RCharacter>;
export type RList = RProxy<RWorker.RList>;
export type RRaw = RProxy<RWorker.RRaw>;
export type RCall = RProxy<RWorker.RCall>;
export type RFunction = RProxy<RWorker.RFunction> & ((...args: unknown[]) => Promise<unknown>);
/**
* Test for an RObject instance
*
* RObject is the user facing interface to R objects.
* @param {any} value The object to test.
* @returns {boolean} True if the object is an instance of an RObject.
*/
export declare function isRObject(value: any): value is RObject;
/**
* Test for an RNull instance
* @param {any} value The object to test.
* @returns {boolean} True if the object is an instance of an RNull.
*/
export declare function isRNull(value: any): value is RNull;
/**
* Test for an RSymbol instance
* @param {any} value The object to test.
* @returns {boolean} True if the object is an instance of an RSymbol.
*/
export declare function isRSymbol(value: any): value is RSymbol;
/**
* Test for an RPairlist instance
* @param {any} value The object to test.
* @returns {boolean} True if the object is an instance of an RPairlist.
*/
export declare function isRPairlist(value: any): value is RPairlist;
/**
* Test for an REnvironment instance
* @param {any} value The object to test.
* @returns {boolean} True if the object is an instance of an REnvironment.
*/
export declare function isREnvironment(value: any): value is REnvironment;
/**
* Test for an RLogical instance
* @param {any} value The object to test.
* @returns {boolean} True if the object is an instance of an RLogical.
*/
export declare function isRLogical(value: any): value is RLogical;
/**
* Test for an RInteger instance
* @param {any} value The object to test.
* @returns {boolean} True if the object is an instance of an RInteger.
*/
export declare function isRInteger(value: any): value is RInteger;
/**
* Test for an RDouble instance
* @param {any} value The object to test.
* @returns {boolean} True if the object is an instance of an RDouble.
*/
export declare function isRDouble(value: any): value is RDouble;
/**
* Test for an RComplex instance
* @param {any} value The object to test.
* @returns {boolean} True if the object is an instance of an RComplex.
*/
export declare function isRComplex(value: any): value is RComplex;
/**
* Test for an RCharacter instance
* @param {any} value The object to test.
* @returns {boolean} True if the object is an instance of an RCharacter.
*/
export declare function isRCharacter(value: any): value is RCharacter;
/**
* Test for an RList instance
* @param {any} value The object to test.
* @returns {boolean} True if the object is an instance of an RList.
*/
export declare function isRList(value: any): value is RList;
/**
* Test for an RRaw instance
* @param {any} value The object to test.
* @returns {boolean} True if the object is an instance of an RRaw.
*/
export declare function isRRaw(value: any): value is RRaw;
/**
* Test for an RCall instance
* @param {any} value The object to test.
* @returns {boolean} True if the object is an instance of an RCall.
*/
export declare function isRCall(value: any): value is RCall;
/**
* Test for an RFunction instance
* @param {any} value The object to test.
* @returns {boolean} True if the object is an instance of an RFunction.
*/
export declare function isRFunction(value: any): value is RFunction;

View file

@ -0,0 +1,225 @@
import { Complex, NamedEntries, NamedObject, WebRDataRaw, WebRDataScalar } from './robj';
import { WebRData, WebRDataAtomic, RPtr, RType, RTypeNumber } from './robj';
import { WebRDataJs, WebRDataJsAtomic, WebRDataJsNode } from './robj';
import { WebRDataJsNull, WebRDataJsString, WebRDataJsSymbol } from './robj';
import { ShelterID } from './webr-chan';
export type RHandle = RObject | RPtr;
export declare function handlePtr(x: RHandle): RPtr;
export declare const shelters: Map<string, number[]>;
export declare function keep(shelter: ShelterID, x: RHandle): void;
export declare function destroy(shelter: ShelterID, x: RHandle): void;
export declare function purge(shelter: ShelterID): void;
export interface ToJsOptions {
depth: number;
}
export type Nullable<T> = T | RNull;
export declare class RObjectBase {
ptr: RPtr;
constructor(ptr: RPtr);
type(): RType;
}
export declare class RObject extends RObjectBase {
#private;
constructor(data: WebRData);
static wrap<T extends typeof RObject>(this: T, ptr: RPtr): InstanceType<T>;
get [Symbol.toStringTag](): string;
/** @internal */
static getPersistentObject(prop: keyof typeof objs): unknown;
/** @internal */
getPropertyValue(prop: keyof this): unknown;
inspect(): void;
isNull(): this is RNull;
isUnbound(): boolean;
attrs(): Nullable<RPairlist>;
setNames(values: (string | null)[] | null): this;
names(): (string | null)[] | null;
includes(name: string): boolean | null;
toJs(options?: ToJsOptions, depth?: number): WebRDataJs;
subset(prop: number | string): RObject;
get(prop: number | string): RObject;
getDollar(prop: string): RObject;
pluck(...path: (string | number)[]): RObject | undefined;
set(prop: string | number, value: RObject | WebRDataRaw): RObject;
/** @internal */
static getMethods(obj: RObject): string[];
}
export declare class RNull extends RObject {
constructor();
toJs(): WebRDataJsNull;
}
export declare class RSymbol extends RObject {
constructor(x: WebRDataScalar<string>);
toJs(): WebRDataJsSymbol;
toObject(): {
printname: string | null;
symvalue: RPtr | null;
internal: RPtr | null;
};
toString(): string;
printname(): RString;
symvalue(): RObject;
internal(): RObject;
}
export declare class RPairlist extends RObject {
constructor(val: WebRData);
get length(): number;
toArray(options?: ToJsOptions): WebRData[];
toObject({ allowDuplicateKey, allowEmptyKey, depth, }?: {
allowDuplicateKey?: boolean | undefined;
allowEmptyKey?: boolean | undefined;
depth?: number | undefined;
}): NamedObject<WebRData>;
entries(options?: ToJsOptions): NamedEntries<WebRData>;
toJs(options?: ToJsOptions, depth?: number): WebRDataJsNode;
includes(name: string): boolean;
setcar(obj: RObject): void;
car(): RObject;
cdr(): Nullable<RPairlist>;
tag(): Nullable<RSymbol>;
}
export declare class RCall extends RObject {
constructor(val: WebRData);
setcar(obj: RObject): void;
car(): RObject;
cdr(): Nullable<RPairlist>;
eval(): RObject;
}
export declare class RList extends RObject {
constructor(val: WebRData);
get length(): number;
toArray(options?: {
depth: number;
}): WebRData[];
toObject({ allowDuplicateKey, allowEmptyKey, depth, }?: {
allowDuplicateKey?: boolean | undefined;
allowEmptyKey?: boolean | undefined;
depth?: number | undefined;
}): NamedObject<WebRData>;
entries(options?: {
depth: number;
}): NamedEntries<WebRData>;
toJs(options?: {
depth: number;
}, depth?: number): WebRDataJsNode;
}
export declare class RFunction extends RObject {
exec(...args: (WebRDataRaw | RObject)[]): RObject;
}
export declare class RString extends RObject {
constructor(x: WebRDataScalar<string>);
toString(): string;
toJs(): WebRDataJsString;
}
export declare class REnvironment extends RObject {
constructor(val?: WebRData);
ls(all?: boolean, sorted?: boolean): string[];
bind(name: string, value: WebRData): void;
names(): string[];
frame(): RObject;
subset(prop: number | string): RObject;
toObject({ depth }?: {
depth?: number | undefined;
}): NamedObject<WebRData>;
toJs(options?: {
depth: number;
}, depth?: number): WebRDataJsNode;
}
type TypedArray = Int8Array | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array;
export type atomicType = number | boolean | Complex | string;
declare abstract class RVectorAtomic<T extends atomicType> extends RObject {
constructor(val: WebRDataAtomic<T>, kind: RType, newSetter: (ptr: RPtr) => (v: any, i: number) => void);
get length(): number;
get(prop: number | string): this;
subset(prop: number | string): this;
getDollar(prop: string): RObject;
detectMissing(): boolean[];
abstract toTypedArray(): TypedArray;
toArray(): (T | null)[];
toObject({ allowDuplicateKey, allowEmptyKey }?: {
allowDuplicateKey?: boolean | undefined;
allowEmptyKey?: boolean | undefined;
}): NamedObject<T | null>;
entries(): NamedEntries<T | null>;
toJs(): WebRDataJsAtomic<T>;
}
export declare class RLogical extends RVectorAtomic<boolean> {
#private;
constructor(val: WebRDataAtomic<boolean>);
getBoolean(idx: number): boolean | null;
toBoolean(): boolean;
toTypedArray(): Int32Array;
toArray(): (boolean | null)[];
}
export declare class RInteger extends RVectorAtomic<number> {
#private;
constructor(val: WebRDataAtomic<number>);
getNumber(idx: number): number | null;
toNumber(): number;
toTypedArray(): Int32Array;
}
export declare class RDouble extends RVectorAtomic<number> {
#private;
constructor(val: WebRDataAtomic<number>);
getNumber(idx: number): number | null;
toNumber(): number;
toTypedArray(): Float64Array;
}
export declare class RComplex extends RVectorAtomic<Complex> {
#private;
constructor(val: WebRDataAtomic<Complex>);
getComplex(idx: number): Complex | null;
toComplex(): Complex;
toTypedArray(): Float64Array;
toArray(): (Complex | null)[];
}
export declare class RCharacter extends RVectorAtomic<string> {
#private;
constructor(val: WebRDataAtomic<string>);
getString(idx: number): string | null;
toString(): string;
toTypedArray(): Uint32Array;
toArray(): (string | null)[];
}
export declare class RRaw extends RVectorAtomic<number> {
#private;
constructor(val: WebRDataAtomic<number>);
getNumber(idx: number): number | null;
toNumber(): number;
toTypedArray(): Uint8Array;
}
export declare function getRWorkerClass(type: RTypeNumber): typeof RObject;
/**
* Test for an RWorker.RObject instance.
*
* RWorker.RObject is the internal interface to R objects, intended to be used
* on the worker thread.
*
* @private
* @param {any} value The object to test.
* @return {boolean} True if the object is an instance of an RObject.
*/
export declare function isRObject(value: any): value is RObject;
/**
* A store for persistent R objects, initialised at R startup.
*/
export declare let objs: {
baseEnv: REnvironment;
bracket2Symbol: RSymbol;
bracketSymbol: RSymbol;
dollarSymbol: RSymbol;
emptyEnv: REnvironment;
false: RLogical;
globalEnv: REnvironment;
na: RLogical;
namesSymbol: RSymbol;
naString: RObject;
null: RNull;
true: RLogical;
unboundValue: RObject;
};
/**
* Populate the persistent R object store.
* @internal
*/
export declare function initPersistentObjects(): void;
export {};

113
docs/shinylive/webr/webR/robj.d.ts vendored Normal file
View file

@ -0,0 +1,113 @@
/**
* Common module for working with R objects.
* @module RObject
*/
import * as RMain from './robj-main';
import * as RWorker from './robj-worker';
export type RPtr = number;
export declare const RTypeMap: {
readonly null: 0;
readonly symbol: 1;
readonly pairlist: 2;
readonly closure: 3;
readonly environment: 4;
readonly promise: 5;
readonly call: 6;
readonly special: 7;
readonly builtin: 8;
readonly string: 9;
readonly logical: 10;
readonly integer: 13;
readonly double: 14;
readonly complex: 15;
readonly character: 16;
readonly dots: 17;
readonly any: 18;
readonly list: 19;
readonly expression: 20;
readonly bytecode: 21;
readonly pointer: 22;
readonly weakref: 23;
readonly raw: 24;
readonly s4: 25;
readonly new: 30;
readonly free: 31;
readonly function: 99;
};
export type RType = keyof typeof RTypeMap;
export type RTypeNumber = (typeof RTypeMap)[keyof typeof RTypeMap];
export type Complex = {
re: number;
im: number;
};
export type WebRDataRaw = number | string | boolean | undefined | null | void | Complex | Error | ArrayBuffer | ArrayBufferView | Array<WebRDataRaw> | Map<WebRDataRaw, WebRDataRaw> | Set<WebRDataRaw> | {
[key: string]: WebRDataRaw;
};
export type NamedEntries<T> = [string | null, T][];
export type NamedObject<T> = {
[key: string]: T;
};
/**
* A union of JavaScript types that are able to be converted into an R object.
*
* `WebRData` is used both as a general input argument for R object construction
* and also as a general return type when converting R objects into JavaScript.
*
*/
export type WebRData = RMain.RObject | RWorker.RObjectBase | RWorker.RObject | WebRDataRaw | WebRDataJs | WebRData[] | {
[key: string]: WebRData;
};
/**
* A subset of {@link WebRData} for JavaScript objects that can be converted
* into R atomic vectors.
* @typeParam T The JavaScript scalar type associated with the atomic vector.
*/
export type WebRDataAtomic<T> = WebRDataScalar<T> | (T | null)[] | WebRDataJsAtomic<T> | NamedObject<T | null>;
/**
* `WebRDataJs` objects form a tree structure, used when serialising R objects
* into a JavaScript respresentation.
*
* Nested R objects are serialised using the {@link WebRDataJsNode} type,
* forming branches in the resulting tree structure, with leaves formed by the
* remaining types.
*/
export type WebRDataJs = WebRDataJsNull | WebRDataJsString | WebRDataJsSymbol | WebRDataJsNode | WebRDataJsAtomic<RWorker.atomicType>;
export type WebRDataJsNull = {
type: 'null';
};
export type WebRDataJsString = {
type: 'string';
value: string;
};
export type WebRDataJsSymbol = {
type: 'symbol';
printname: string | null;
symvalue: RPtr | null;
internal: RPtr | null;
};
export type WebRDataJsNode = {
type: 'list' | 'pairlist' | 'environment';
names: (string | null)[] | null;
values: (WebRDataRaw | RWorker.RObject | RMain.RObject | WebRDataJs)[];
};
export type WebRDataJsAtomic<T> = {
type: 'logical' | 'integer' | 'double' | 'complex' | 'character' | 'raw';
names: (string | null)[] | null;
values: (T | null)[];
};
/**
* Test for a {@link WebRDataJs} instance.
* @param {any} value The object to test.
* @returns {boolean} True if the object is an instance of a {@link WebRDataJs}.
*/
export declare function isWebRDataJs(value: any): value is WebRDataJs;
/**
* A subset of WebRData for scalar JavaScript objects.
*/
export type WebRDataScalar<T> = T | RMain.RObject | RWorker.RObjectBase;
/**
* Test if an object is of type {@link Complex}.
* @param {any} value The object to test.
* @returns {boolean} True if the object is of type {@link Complex}.
*/
export declare function isComplex(value: any): value is Complex;

25
docs/shinylive/webr/webR/utils-r.d.ts vendored Normal file
View file

@ -0,0 +1,25 @@
import { WebRData, RPtr } from './robj';
import { RObject, RHandle } from './robj-worker';
export declare function protect<T extends RHandle>(x: T): T;
export declare function protectInc<T extends RHandle>(x: T, prot: {
n: number;
}): T;
export declare function protectWithIndex(x: RHandle): {
loc: number;
ptr: RPtr;
};
export declare function unprotectIndex(index: {
ptr: RPtr;
}): void;
export declare function reprotect<T extends RHandle>(x: T, index: {
loc: number;
ptr: RPtr;
}): T;
export declare function unprotect(n: number): void;
export declare function envPoke(env: RHandle, sym: RHandle, value: RHandle): void;
export declare function parseEvalBare(code: string, env: WebRData): RObject;
export declare class UnwindProtectException extends Error {
cont: RPtr;
constructor(message: string, cont: RPtr);
}
export declare function safeEval(call: RHandle, env: RHandle): RPtr;

12
docs/shinylive/webr/webR/utils.d.ts vendored Normal file
View file

@ -0,0 +1,12 @@
export type ResolveFn = (_value?: unknown) => void;
export type RejectFn = (_reason?: any) => void;
export declare function promiseHandles(): {
resolve: (_value?: unknown) => void;
reject: (_reason?: any) => void;
promise: Promise<unknown>;
};
export declare function sleep(ms: number): Promise<unknown>;
export declare function replaceInObject<T>(obj: T | T[], test: (obj: any) => boolean, replacer: (obj: any, ...replacerArgs: any[]) => unknown, ...replacerArgs: unknown[]): T | T[];
export declare function newCrossOriginWorker(url: string, cb: (worker: Worker) => void): void;
export declare function isCrossOrigin(urlString: string): boolean;
export declare function throwUnreachable(context?: string): void;

197
docs/shinylive/webr/webR/webr-chan.d.ts vendored Normal file
View file

@ -0,0 +1,197 @@
/**
* @module WebRChan
*/
import { Message } from './chan/message';
import { UUID as ShelterID } from './chan/task-common';
import { EmPtr } from './emscripten';
import { WebRPayloadWorker, WebRPayloadPtr } from './payload';
import { RType, WebRData } from './robj';
import type { FSType, FSMountOptions } from './webr-main';
export { isUUID as isShelterID, UUID as ShelterID } from './chan/task-common';
/** @internal */
export interface CallRObjectMethodMessage extends Message {
type: 'callRObjectMethod';
data: {
payload?: WebRPayloadPtr;
prop: string;
args: WebRPayloadWorker[];
shelter?: ShelterID;
};
}
/**
* The configuration settings used when installing R packages.
*/
export interface InstallPackagesOptions {
/**
* The R package repository from which to download packages.
* Default: The configured default webR package repository.
*/
repos?: string;
/**
* If `true`, do not output downloading messages.
* Default: `false`.
*/
quiet?: boolean;
/**
* If `true`, attempt to mount packages using filesystem images.
* Default: `true`.
*/
mount?: boolean;
}
/** @internal */
export interface InstallPackagesMessage extends Message {
type: 'installPackage';
data: {
name: string;
options: InstallPackagesOptions;
};
}
/**
* The configuration settings used when evaluating R code.
*/
export interface EvalROptions {
/**
* The R environment to evaluate within.
* Default: The global environment.
*/
env?: WebRData;
/**
* Should the stdout and stderr output streams be captured and returned?
* Default: `true`.
*/
captureStreams?: boolean;
/**
* Should conditions raised during execution be captured and returned?
* Default: `true`.
*/
captureConditions?: boolean;
/**
* Should the code automatically print output as if it were written at an R console?
* Default: `false`.
*/
withAutoprint?: boolean;
/**
* Should an R error condition be re-thrown as a JavaScript exception?
* Default: `true`.
*/
throwJsException?: boolean;
/**
* Should the code be executed using a `tryCatch` with handlers in place?
* Default: `true`.
*/
withHandlers?: boolean;
}
/** @internal */
export interface CaptureRMessage extends Message {
type: 'captureR';
data: {
code: string;
options: EvalROptions;
shelter: ShelterID;
};
}
/** @internal */
export interface EvalRMessage extends Message {
type: 'evalR';
data: {
code: string;
options: EvalROptions;
shelter: ShelterID;
outputType?: EvalRMessageOutputType;
};
}
export type EvalRMessageOutputType = 'void' | 'boolean' | 'boolean[]' | 'number' | 'number[]' | 'string' | 'string[]';
/** @internal */
export interface EvalRMessageRaw extends Message {
type: 'evalRRaw';
data: {
code: string;
options: EvalROptions;
outputType: EvalRMessageOutputType;
};
}
/** @internal */
export interface FSMessage extends Message {
type: 'lookupPath' | 'mkdir' | 'rmdir' | 'unlink' | 'unmount';
data: {
path: string;
};
}
/** @internal */
export interface FSMountMessage extends Message {
type: 'mount';
data: {
type: FSType;
options: FSMountOptions;
mountpoint: string;
};
}
/** @internal */
export interface FSReadFileMessage extends Message {
type: 'readFile';
data: {
path: string;
flags?: string;
};
}
/** @internal */
export interface FSWriteFileMessage extends Message {
type: 'writeFile';
data: {
path: string;
data: ArrayBufferView;
flags?: string;
};
}
/** @internal */
export interface InvokeWasmFunctionMessage extends Message {
type: 'invokeWasmFunction';
data: {
ptr: EmPtr;
args: number[];
};
}
/** @internal */
export interface NewRObjectMessage extends Message {
type: 'newRObject';
data: {
obj: WebRData;
objType: RType | 'object';
shelter: ShelterID;
};
}
/** @internal */
export interface NewShelterMessage extends Message {
type: 'newShelter';
}
/** @internal */
export interface ShelterMessage extends Message {
type: 'shelterPurge' | 'shelterSize';
data: ShelterID;
}
/** @internal */
export interface ShelterDestroyMessage extends Message {
type: 'shelterDestroy';
data: {
id: ShelterID;
obj: WebRPayloadPtr;
};
}
export interface CanvasMessage extends Message {
type: 'canvas';
data: {
event: 'canvasNewPage';
} | {
event: 'canvasImage';
image: ImageBitmap;
};
}
export interface PagerMessage extends Message {
type: 'pager';
data: {
path: string;
header: string;
title: string;
deleteFile: boolean;
};
}

315
docs/shinylive/webr/webR/webr-main.d.ts vendored Normal file
View file

@ -0,0 +1,315 @@
/**
* The webR JavaScript API.
* @module WebR
*/
import { ChannelMain } from './chan/channel';
import { ChannelType } from './chan/channel-common';
import { Message } from './chan/message';
import { EmPtr } from './emscripten';
import { newRClassProxy } from './proxy';
import { RCharacter, RComplex, RDouble } from './robj-main';
import { REnvironment, RSymbol, RInteger } from './robj-main';
import { RList, RLogical, RNull, RObject, RPairlist, RRaw, RString, RCall } from './robj-main';
import * as RWorker from './robj-worker';
import { EvalROptions, InstallPackagesOptions } from './webr-chan';
export { Console, ConsoleCallbacks } from './console';
export * from './robj-main';
export * from './error';
export { ChannelType } from './chan/channel-common';
/**
* The webR FS API for interacting with the Emscripten Virtual File System.
*/
export interface WebRFS {
/**
* Lookup information about a file or directory node in the Emscripten
* virtual file system.
* @param {string} path Path to the requested node.
* @returns {Promise<FSNode>} The requested node.
*/
lookupPath: (path: string) => Promise<FSNode>;
/**
* Create a directory on the Emscripten virtual file system.
* @param {string} path Path of the directory to create.
* @returns {Promise<FSNode>} The newly created directory node.
*/
mkdir: (path: string) => Promise<FSNode>;
/**
* Get the content of a file on the Emscripten virtual file system.
* @param {string} path Path of the file to read.
* @param {string} [flags] Open the file with the specified flags.
* @returns {Promise<Uint8Array>} The content of the requested file.
*/
readFile: (path: string, flags?: string) => Promise<Uint8Array>;
/**
* Remove a directory on the Emscripten virtual file system.
* @param {string} path Path of the directory to remove.
*/
rmdir: (path: string) => Promise<void>;
/**
* Write a new file to the Emscripten virtual file system.
* @param {string} path Path of the new file.
* @param {Uint8Array} data The content of the new file.
* @param {string} [flags] Open the file with the specified flags.
*/
writeFile: (path: string, data: ArrayBufferView, flags?: string) => Promise<void>;
/**
* Unlink a node on the Emscripten virtual file system. If that node was the
* last link to a file it is is deleted.
* @param {string} path Path of the target node.
*/
unlink: (path: string) => Promise<void>;
}
/** A filesystem entry in the Emscripten Virtual File System */
export type FSNode = {
id: number;
name: string;
mode: number;
isFolder: boolean;
contents?: {
[key: string]: FSNode;
};
mounted: null | {
mountpoint: string;
root: FSNode;
};
};
/** An Emscripten Filesystem type */
export type FSType = 'NODEFS' | 'WORKERFS';
/**
* Configuration settings to be used when mounting Filesystem objects with
* Emscripten
* */
export type FSMountOptions<T extends FSType = FSType> = T extends 'NODEFS' ? {
root: string;
} : {
blobs?: Array<{
name: string;
data: Blob;
}>;
files?: Array<File | FileList>;
packages?: Array<{
metadata: any;
blob: Blob;
}>;
};
/**
* The configuration settings to be used when starting webR.
*/
export interface WebROptions {
/**
* Command line arguments to be passed to R.
* Default: `[]`.
*/
RArgs?: string[];
/**
* Environment variables to be made available for the R process.
* Default: `{ R_HOME: '/usr/lib/R', R_ENABLE_JIT: 0 }`.
*/
REnv?: {
[key: string]: string;
};
/**
* The base URL used for downloading R WebAssembly binaries.
* Default: `'https://webr.r-wasm.org/[version]/'`
*/
baseUrl?: string;
/**
* The repo URL to use when downloading R WebAssembly packages.
* Default: `'https://repo.r-wasm.org/`
*/
repoUrl?: string;
/**
* The base URL from where to load JavaScript worker scripts when loading
* webR with the ServiceWorker communication channel mode.
* Default: `''`
*/
serviceWorkerUrl?: string;
/**
* The WebAssembly user's home directory and initial working directory.
* Default: `'/home/web_user'`
*/
homedir?: string;
/**
* Start R in interactive mode?
* Default: `true`.
*/
interactive?: boolean;
/**
* Set the communication channel type to be used.
* Default: `channelType.Automatic`
*/
channelType?: (typeof ChannelType)[keyof typeof ChannelType];
/**
* Create the lazy virtual filesystem entries before starting R?
* Default: `true`.
*/
createLazyFilesystem?: boolean;
}
/**
* The webR class is used to initialize and interact with the webR system.
*
* Start webR by constructing an instance of the WebR class, optionally passing
* an options argument of type {@link WebROptions}. WebR will begin to download
* and start a version of R built for WebAssembly in a worker thread.
*/
export declare class WebR {
#private;
globalShelter: Shelter;
RObject: ReturnType<typeof newRClassProxy<typeof RWorker.RObject, RObject>>;
RLogical: ReturnType<typeof newRClassProxy<typeof RWorker.RLogical, RLogical>>;
RInteger: ReturnType<typeof newRClassProxy<typeof RWorker.RInteger, RInteger>>;
RDouble: ReturnType<typeof newRClassProxy<typeof RWorker.RDouble, RDouble>>;
RCharacter: ReturnType<typeof newRClassProxy<typeof RWorker.RCharacter, RCharacter>>;
RComplex: ReturnType<typeof newRClassProxy<typeof RWorker.RComplex, RComplex>>;
RRaw: ReturnType<typeof newRClassProxy<typeof RWorker.RRaw, RRaw>>;
RList: ReturnType<typeof newRClassProxy<typeof RWorker.RList, RList>>;
RPairlist: ReturnType<typeof newRClassProxy<typeof RWorker.RPairlist, RPairlist>>;
REnvironment: ReturnType<typeof newRClassProxy<typeof RWorker.REnvironment, REnvironment>>;
RSymbol: ReturnType<typeof newRClassProxy<typeof RWorker.RSymbol, RSymbol>>;
RString: ReturnType<typeof newRClassProxy<typeof RWorker.RString, RString>>;
RCall: ReturnType<typeof newRClassProxy<typeof RWorker.RCall, RCall>>;
objs: {
baseEnv: REnvironment;
globalEnv: REnvironment;
null: RNull;
true: RLogical;
false: RLogical;
na: RLogical;
};
Shelter: new () => Promise<Shelter>;
constructor(options?: WebROptions);
/**
* @returns {Promise<void>} A promise that resolves once webR has been
* intialised.
*/
init(): Promise<unknown>;
/**
* Close the communication channel between the main thread and the worker
* thread cleanly. Once this has been executed, webR will be unable to
* continue.
*/
close(): void;
/**
* Read from the communication channel and return an output message.
* @returns {Promise<Message>} The output message
*/
read(): Promise<Message>;
/**
* Flush the output queue in the communication channel and return all output
* messages.
* @returns {Promise<Message[]>} The output messages
*/
flush(): Promise<Message[]>;
/**
* Send a message to the communication channel input queue.
* @param {Message} msg Message to be added to the input queue.
*/
write(msg: Message): void;
/**
* Send a line of standard input to the communication channel input queue.
* @param {string} input Message to be added to the input queue.
*/
writeConsole(input: string): void;
/** Attempt to interrupt a running R computation. */
interrupt(): void;
/**
* Install a list of R packages from a Wasm binary package repo.
* @param {string[]} packages An array of R package names.
* @param {InstallPackagesOptions} [options] Options to be used when
* installing webR packages.
*/
installPackages(packages: string[], options?: InstallPackagesOptions): Promise<void>;
/**
* Destroy an R object reference.
* @param {RObject} x An R object reference.
*/
destroy(x: RObject): Promise<void>;
/**
* Evaluate the given R code.
*
* Stream outputs and any conditions raised during exectution are written to
* the JavaScript console.
* @param {string} code The R code to evaluate.
* @param {EvalROptions} [options] Options for the execution environment.
* @returns {Promise<RObject>} The result of the computation.
*/
evalR(code: string, options?: EvalROptions): Promise<RObject>;
evalRVoid(code: string, options?: EvalROptions): Promise<void>;
evalRBoolean(code: string, options?: EvalROptions): Promise<boolean>;
evalRNumber(code: string, options?: EvalROptions): Promise<number>;
evalRString(code: string, options?: EvalROptions): Promise<string>;
/**
* Evaluate the given R code, returning the result as a raw JavaScript object.
* @param {string} code The R code to evaluate.
* @param {EvalRMessageOutputType} outputType JavaScript type to return the result as.
* @param {EvalROptions} [options] Options for the execution environment.
* @returns {Promise<unknown>} The result of the computation.
*/
evalRRaw(code: string, outputType: 'void', options?: EvalROptions): Promise<void>;
evalRRaw(code: string, outputType: 'boolean', options?: EvalROptions): Promise<boolean>;
evalRRaw(code: string, outputType: 'boolean[]', options?: EvalROptions): Promise<boolean[]>;
evalRRaw(code: string, outputType: 'number', options?: EvalROptions): Promise<number>;
evalRRaw(code: string, outputType: 'number[]', options?: EvalROptions): Promise<number[]>;
evalRRaw(code: string, outputType: 'string', options?: EvalROptions): Promise<string>;
evalRRaw(code: string, outputType: 'string[]', options?: EvalROptions): Promise<string[]>;
invokeWasmFunction(ptr: EmPtr, ...args: number[]): Promise<EmPtr>;
FS: {
lookupPath: (path: string) => Promise<FSNode>;
mkdir: (path: string) => Promise<FSNode>;
mount: <T extends FSType>(type: T, options: FSMountOptions<T>, mountpoint: string) => Promise<void>;
readFile: (path: string, flags?: string) => Promise<Uint8Array>;
rmdir: (path: string) => Promise<void>;
writeFile: (path: string, data: ArrayBufferView, flags?: string) => Promise<void>;
unlink: (path: string) => Promise<void>;
unmount: (mountpoint: string) => Promise<void>;
};
}
/** WebR shelters provide fine-grained control over the lifetime of R objects. */
export declare class Shelter {
#private;
RObject: ReturnType<typeof newRClassProxy<typeof RWorker.RObject, RObject>>;
RLogical: ReturnType<typeof newRClassProxy<typeof RWorker.RLogical, RLogical>>;
RInteger: ReturnType<typeof newRClassProxy<typeof RWorker.RInteger, RInteger>>;
RDouble: ReturnType<typeof newRClassProxy<typeof RWorker.RDouble, RDouble>>;
RCharacter: ReturnType<typeof newRClassProxy<typeof RWorker.RCharacter, RCharacter>>;
RComplex: ReturnType<typeof newRClassProxy<typeof RWorker.RComplex, RComplex>>;
RRaw: ReturnType<typeof newRClassProxy<typeof RWorker.RRaw, RRaw>>;
RList: ReturnType<typeof newRClassProxy<typeof RWorker.RList, RList>>;
RPairlist: ReturnType<typeof newRClassProxy<typeof RWorker.RPairlist, RPairlist>>;
REnvironment: ReturnType<typeof newRClassProxy<typeof RWorker.REnvironment, REnvironment>>;
RSymbol: ReturnType<typeof newRClassProxy<typeof RWorker.RSymbol, RSymbol>>;
RString: ReturnType<typeof newRClassProxy<typeof RWorker.RString, RString>>;
RCall: ReturnType<typeof newRClassProxy<typeof RWorker.RCall, RCall>>;
/** @internal */
constructor(chan: ChannelMain);
/** @internal */
init(): Promise<void>;
purge(): Promise<void>;
destroy(x: RObject): Promise<void>;
size(): Promise<number>;
/**
* Evaluate the given R code.
*
* Stream outputs and any conditions raised during exectution are written to
* the JavaScript console. The returned R object is protected by the shelter.
* @param {string} code The R code to evaluate.
* @param {EvalROptions} [options] Options for the execution environment.
* @returns {Promise<RObject>} The result of the computation.
*/
evalR(code: string, options?: EvalROptions): Promise<RObject>;
/**
* Evaluate the given R code, capturing output.
*
* Stream outputs and conditions raised during exectution 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.
*/
captureR(code: string, options?: EvalROptions): Promise<{
result: RObject;
output: unknown[];
}>;
}

View file

@ -0,0 +1 @@
export {};