Skip to content
/ wrp-ts Public

TypeScript Implementation of Webview/Worker Request Protocol

License

Notifications You must be signed in to change notification settings

pbkit/wrp-ts

Repository files navigation

WRP - Webview/Worker Request Protocol

pronounce as wrap(ræp)

Design

architecture diagram

  • Glue - Platform-specific code to implement sockets
  • Socket - Way for sending and receiving data between the two platforms
  • Channel - An interface that allows information to be exchanged in units of messages using sockets.
  • Guest - An interface that can send requests to hosts using channels.
  • Host - An interface that allows you to process and respond to requests received from guests.

wrp channel packet diagram

Whenever the channel sends a message, it writes the message size as a 4-byte little-endian integer to the socket, and then writes a message payload as that size.

The message payload is defined in the ./src/wrp.proto file.

sequenceDiagram
  participant H as WrpHost
  participant G as WrpGuest
  H->>G: HostInitialize
  Note over H, G: Send available methods
  loop
    G->>+H: GuestReqStart
    H-->>G: HostResStart
    par request
      loop
        G-->>H: GuestReqPayload
      end
      G-->>H: GuestReqFinish
    end
    par response
      loop
        H-->>G: HostResPayload
      end
      H-->>-G: HostResFinish
    end
  end
Loading

Types

// Glue implementation provides socket object.
type Socket = Reader & Writer;
interface Reader {
  read(p: Uint8Array): Promise<number | null>;
}
interface Writer {
  write(p: Uint8Array): Promise<number>;
}

// Channel provides a per-message communication method.
interface WrpChannel {
  listen(): AsyncGenerator<WrpMessage>;
  send(message: WrpMessage): Promise<void>;
}

type Metadata = Record<string, string>;
interface LazyMetadata {
  [key: string]:
    | undefined
    | string
    | Promise<string | undefined>
    | (() => string | undefined)
    | (() => Promise<string | undefined>);
}

// Guest provides a way to send requests to the host.
interface WrpGuest {
  availableMethods: Set<string>;
  request(
    methodName: string,
    req: AsyncGenerator<Uint8Array>,
    metadata?: LazyMetadata,
  ): {
    res: AsyncGenerator<Uint8Array>;
    header: Promise<Metadata>;
    trailer: Promise<Metadata>;
  };
}

// Host provides a way to handle and respond to requests from guests.
interface WrpHost {
  listen(): AsyncGenerator<WrpRequest>;
}
interface WrpRequest {
  methodName: string;
  metadata: Metadata;
  req: AsyncGenerator<Uint8Array>;
  sendHeader(value: Metadata): void;
  sendPayload(value: Uint8Array): void;
  sendTrailer(value: Metadata): void;
}