All files / rpc-calls/src/caller FetchCaller.ts

100% Statements 13/13
50% Branches 1/2
100% Functions 6/6
100% Lines 13/13

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 651x                                       1x       17x 17x 17x         17x     21x         21x 21x                 29x       29x       2x       17x      
import {UnaryCaller} from './UnaryCaller';
import type {UnaryCallerOptions} from './UnaryCaller';
import type {Observable} from 'rxjs';
import type {Caller, CallerMethods} from './types';
 
export interface FetchCallerOptions extends Omit<UnaryCallerOptions, 'send'> {
  /** URL of the RPC endpoint. */
  url: string;
 
  /** Custom `fetch` implementation, defaults to global `fetch`. */
  fetch?: typeof fetch;
 
  /** Additional HTTP headers to include in every request. */
  headers?: Record<string, string>;
}
 
/**
 * HTTP-based RPC caller built on top of {@link UnaryCaller}. Sends batched
 * messages to the server via `fetch()` POST requests.
 */
export class FetchCaller<Methods extends CallerMethods<any> = CallerMethods> implements Caller<Methods> {
  public readonly caller: UnaryCaller<Methods>;
 
  constructor(options: FetchCallerOptions) {
    const {url, headers, fetch: customFetch, ...rest} = options;
    const currentFetch = customFetch || fetch;
    const reqHeaders: Record<string, string> = {
      'Content-Type': 'application/octet-stream',
      ...headers,
    };
 
    this.caller = new UnaryCaller<Methods>({
      ...rest,
      send: async (data: Uint8Array): Promise<Uint8Array> => {
        const response = await currentFetch(url, {
          method: 'POST',
          headers: reqHeaders,
          body: data as any,
        });
        const buffer = await response.arrayBuffer();
        return new Uint8Array(buffer);
      },
    });
  }
 
  public call$<K extends keyof Methods>(
    method: K,
    data: Observable<Methods[K][0]> | Methods[K][0],
  ): Observable<Methods[K][1]> {
    return this.caller.call$(method, data);
  }
 
  public async call<K extends keyof Methods>(method: K, request: Methods[K][0]): Promise<Methods[K][1]> {
    return this.caller.call(method, request);
  }
 
  public notify<K extends keyof Methods>(method: K, data: Methods[K][0]): void {
    this.caller.notify(method, data);
  }
 
  public stop() {
    this.caller.stop();
  }
}