Skip to content

Commit

Permalink
Added JSDoc comments. (#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
DaniGuardiola committed Dec 16, 2023
1 parent a7ccc0a commit 63d54c9
Show file tree
Hide file tree
Showing 5 changed files with 358 additions and 20 deletions.
5 changes: 5 additions & 0 deletions .changeset/big-seahorses-kneel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"rpc-anywhere": minor
---

Added JSDoc comments everywhere.
10 changes: 9 additions & 1 deletion src/create-request-handler.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import { type RPCRequestHandlerObject } from "./types.js";

/**
* Creates a typed RPC request handler in "object" form.
*/
export function createRPCRequestHandler<
const Handler extends RPCRequestHandlerObject,
>(handler: Handler) {
>(
/**
* The RPC request handler object.
*/
handler: Handler,
) {
return handler;
}
151 changes: 141 additions & 10 deletions src/rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ import {
const MAX_ID = 1e10;
const DEFAULT_MAX_REQUEST_TIME = 1000;

/**
* Creates an RPC instance that can send and receive requests, responses
* and messages.
*/
export class RPC<
Schema extends RPCSchema = RPCSchema,
RemoteSchema extends RPCSchema = Schema,
Expand All @@ -28,15 +32,35 @@ export class RPC<
// ------------

#send?: (message: any) => void;
setSend(send: (message: any) => void) {

/**
* Sets the function that will be used to send requests, responses and
* messages to the remote RPC instance.
*/
setSend(
/**
* The function that will be set as the "send" function.
*/
send: (message: any) => void,
) {
this.#send = send;
}

#requestHandler?: RPCRequestHandler<Schema["requests"]>;
setRequestHandler(handler: RPCRequestHandler<Schema["requests"]>) {

/**
* Sets the function that will be used to handle requests from the
* remote RPC instance.
*/
setRequestHandler(
/**
* The function that will be set as the "request handler" function.
*/
handler: RPCRequestHandler<Schema["requests"]>,
) {
this.#requestHandler = handler;
}
getRequestHandler(errorMessageOnUnset: string) {
#getRequestHandler(errorMessageOnUnset: string) {
if (typeof this.#requestHandler === "function") return this.#requestHandler;
return (method: any, params: any) => {
if (typeof this.#requestHandler === "function")
Expand All @@ -50,6 +74,10 @@ export class RPC<
};
}

/**
* Sets the transport that will be used to send and receive requests,
* responses and messages.
*/
setTransport({ send, registerHandler }: RPCTransport) {
this.setSend(send);
registerHandler(this.handle.bind(this));
Expand All @@ -59,12 +87,17 @@ export class RPC<
// ------------

#maxRequestTime: number;
constructor({
transport,
send,
requestHandler,
maxRequestTime = DEFAULT_MAX_REQUEST_TIME,
}: RPCOptions<Schema> = {}) {
constructor(
/**
* The options that will be used to configure the RPC instance.
*/
{
transport,
send,
requestHandler,
maxRequestTime = DEFAULT_MAX_REQUEST_TIME,
}: RPCOptions<Schema> = {},
) {
this.#lastRequestId = 0;

const resolvedSend = transport?.send ?? send;
Expand All @@ -74,13 +107,27 @@ export class RPC<
this.#maxRequestTime = maxRequestTime;
}

/**
* Creates an RPC instance as a client. The passed schema represents
* the remote RPC's (server) schema.
*/
static asClient<RemoteSchema extends RPCSchema = RPCSchema>(
/**
* The options that will be used to configure the RPC instance.
*/
options: RPCOptions<EmptyRPCSchema>,
) {
return new RPC<EmptyRPCSchema, RemoteSchema>(options);
}

/**
* Creates an RPC instance as a server. The passed schema represents
* this RPC's (server) schema.
*/
static asServer<Schema extends RPCSchema = RPCSchema>(
/**
* The options that will be used to configure the RPC instance.
*/
options: RPCOptions<Schema>,
) {
return new RPC<Schema, EmptyRPCSchema>(options);
Expand All @@ -99,6 +146,11 @@ export class RPC<
{ resolve: (result: unknown) => void; reject: (error: Error) => void }
>();
#requestTimeouts = new Map<number, ReturnType<typeof setTimeout>>();

/**
* Sends a request to the remote RPC endpoint and returns a promise
* with the response.
*/
request<Method extends keyof RemoteSchema["requests"]>(
method: Method,
...args: "params" extends keyof RemoteSchema["requests"][Method]
Expand Down Expand Up @@ -133,6 +185,9 @@ export class RPC<
}) as Promise<any>;
}

/**
* A proxy that allows calling requests as if they were functions.
*/
requestProxy = new Proxy(
{},
{
Expand All @@ -146,7 +201,13 @@ export class RPC<
// messages
// --------

/**
* Sends a message to the remote RPC endpoint.
*/
send<Message extends keyof Schema["messages"]>(
/**
* The name of the message to send.
*/
message: Message,
...args: void extends RPCMessagePayload<Schema["messages"], Message>
? []
Expand All @@ -169,16 +230,50 @@ export class RPC<
#wildcardMessageListeners = new Set<
(messageName: any, payload: any) => void
>();

/**
* Adds a listener for a message (or all if "*" is used) from the
* remote RPC endpoint.
*/
addMessageListener(
/**
* The name of the message to listen to. Use "*" to listen to all
* messages.
*/
message: "*",
/**
* The function that will be called when a message is received.
*/
listener: WildcardRPCMessageHandlerFn<RemoteSchema["messages"]>,
): void;
/**
* Adds a listener for a message (or all if "*" is used) from the
* remote RPC endpoint.
*/
addMessageListener<Message extends keyof RemoteSchema["messages"]>(
/**
* The name of the message to listen to. Use "*" to listen to all
* messages.
*/
message: Message,
/**
* The function that will be called when a message is received.
*/
listener: RPCMessageHandlerFn<RemoteSchema["messages"], Message>,
): void;
/**
* Adds a listener for a message (or all if "*" is used) from the
* remote RPC endpoint.
*/
addMessageListener<Message extends keyof RemoteSchema["messages"]>(
/**
* The name of the message to listen to. Use "*" to listen to all
* messages.
*/
message: "*" | Message,
/**
* The function that will be called when a message is received.
*/
listener:
| WildcardRPCMessageHandlerFn<RemoteSchema["messages"]>
| RPCMessageHandlerFn<RemoteSchema["messages"], Message>,
Expand All @@ -192,16 +287,49 @@ export class RPC<
this.#messageListeners.get(message)?.add(listener as any);
}

/**
* Removes a listener for a message (or all if "*" is used) from the
* remote RPC endpoint.
*/
removeMessageListener(
/**
* The name of the message to remove the listener for. Use "*" to
* remove a listener for all messages.
*/
message: "*",
/**
* The listener function that will be removed.
*/
listener: WildcardRPCMessageHandlerFn<RemoteSchema["messages"]>,
): void;
/**
* Removes a listener for a message (or all if "*" is used) from the
* remote RPC endpoint.
*/
removeMessageListener<Message extends keyof RemoteSchema["messages"]>(
/**
* The name of the message to remove the listener for. Use "*" to
* remove a listener for all messages.
*/
message: Message,
/**
* The listener function that will be removed.
*/
listener: RPCMessageHandlerFn<RemoteSchema["messages"], Message>,
): void;
/**
* Removes a listener for a message (or all if "*" is used) from the
* remote RPC endpoint.
*/
removeMessageListener<Message extends keyof RemoteSchema["messages"]>(
/**
* The name of the message to remove the listener for. Use "*" to
* remove a listener for all messages.
*/
message: "*" | Message,
/**
* The listener function that will be removed.
*/
listener:
| WildcardRPCMessageHandlerFn<RemoteSchema["messages"]>
| RPCMessageHandlerFn<RemoteSchema["messages"], Message>,
Expand All @@ -218,6 +346,9 @@ export class RPC<
// message handling
// ----------------

/**
* Handles a request, response or message from the remote RPC endpoint.
*/
async handle(
message:
| RPCRequestFromSchema<Schema["requests"]>
Expand All @@ -238,7 +369,7 @@ export class RPC<
type: "response",
id,
success: true,
payload: await this.getRequestHandler(
payload: await this.#getRequestHandler(
'This RPC instance cannot send requests because the "requestHandler" function is not set. Pass it to the constructor or use "setSend" to enable handling requests.',
)(method, params),
};
Expand Down
4 changes: 4 additions & 0 deletions src/transports/browser-runtime-port.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import { type Browser, type Chrome } from "browser-namespace";

import { type RPCTransport } from "../types.js";

/**
* Creates a transport from a browser runtime port. Useful for RPCs
* between content scripts and service workers in web extensions.
*/
export function createTransportFromBrowserRuntimePort(
port: Browser.Runtime.Port | Chrome.runtime.Port,
): RPCTransport {
Expand Down
Loading

0 comments on commit 63d54c9

Please sign in to comment.