@oada/client
Version:
A lightweight client tool to interact with an OADA-compliant server
254 lines (253 loc) • 6.92 kB
TypeScript
/**
* @license
* Copyright 2021 Open Ag Data Alliance
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import type { EventEmitter } from "eventemitter3";
import type { Tree } from "@oada/types/oada/tree/v1.js";
import { type HTTPTimeouts } from "./http.js";
import type { Change, Json } from "./index.js";
/**
* Supported types for in/out request bodies
*/
export type Body = Json | Uint8Array;
export type ConnectionRequest = {
requestId?: string;
path: string;
/**
* @default false
*/
watch?: boolean;
method: "head" | "get" | "put" | "post" | "delete" | "unwatch";
headers: Record<string, string>;
data?: Body;
} & ({
watch?: false;
} | {
watch: true;
method: "head" | "get" | "put" | "post" | "delete";
});
export interface ConnectionResponse {
requestId: string | string[];
status: number;
statusText: string;
headers: Record<string, string>;
data?: Body;
}
export interface ConnectionChange {
requestId: string[];
resourceId: string;
change: Change[];
}
export type IConnectionResponse = [
response: ConnectionResponse,
updates?: AsyncIterableIterator<[Readonly<ConnectionChange>]>
];
export interface Connection extends EventEmitter {
disconnect(): Promise<void>;
isConnected(): boolean;
awaitConnection(): Promise<void>;
request(request: ConnectionRequest, options?: {
timeout?: number;
signal?: AbortSignal;
}): Promise<IConnectionResponse>;
}
export interface Config {
domain: string;
token?: string;
/** @default 1 */
concurrency?: number;
/** @default 'auto' */
connection?: "auto" | "ws" | "http" | Connection;
userAgent?: string;
timeouts?: number | Partial<HTTPTimeouts>;
}
export type Response = ConnectionResponse;
export interface WatchResponse<C extends Readonly<Change> | ReadonlyArray<Readonly<Change>>> extends Response {
/**
* AsyncIterableIterator of the change feed for the watch
*/
changes: AsyncIterableIterator<C>;
}
export interface GETRequest {
path: string;
tree?: Tree;
timeout?: number;
headers?: Record<string, string>;
}
export interface PersistConfig {
name: string;
recordLapsedTimeout: number;
}
export interface WatchPersist {
lastRev: number;
recordLapsedTimeout: number | undefined;
lastCheck: number | undefined;
items: Map<number, boolean | number>;
recorded: Map<number, boolean | number>;
}
export interface WatchRequestBase {
/**
* @default 'single'
*/
type?: "tree" | "single";
/**
* @default 'head'
*/
initialMethod?: "get" | "head" | "put" | "post" | "delete";
path: string;
rev?: number | string;
persist?: PersistConfig;
timeout?: number;
headers?: Record<string, string>;
}
/**
* Watch whose callback gets single changes
*/
export interface WatchRequestSingle extends WatchRequestBase {
type?: "single";
}
/**
* @deprecated
*/
export interface WatchRequestSingleOld extends WatchRequestBase {
type?: "single";
watchCallback(response: Readonly<Change>): Promise<void>;
}
/**
* Watch whose callback gets change trees
*/
export interface WatchRequestTree extends WatchRequestBase {
type: "tree";
}
/**
* @deprecated
*/
export interface WatchRequestTreeOld extends WatchRequestBase {
type: "tree";
watchCallback(response: ReadonlyArray<Readonly<Change>>): Promise<void>;
}
/**
* Discriminated union of watch for single changes or watch for change trees
*/
export type WatchRequest = WatchRequestSingle | WatchRequestTree | WatchRequestSingleOld | WatchRequestTreeOld;
export interface PUTRequest {
path: string;
data: Body;
contentType?: string;
/** If-Match */
etagIfMatch?: string | readonly string[];
tree?: Tree;
timeout?: number;
headers?: Record<string, string>;
}
export interface POSTRequest {
path: string;
data: Body;
contentType?: string;
tree?: Tree;
timeout?: number;
headers?: Record<string, string>;
}
export interface HEADRequest {
path: string;
timeout?: number;
headers?: Record<string, string>;
}
export interface DELETERequest {
path: string;
timeout?: number;
headers?: Record<string, string>;
}
export interface ENSURERequest {
path: string;
timeout?: number;
tree?: Tree;
data: Json;
headers?: Record<string, string>;
}
/**
* Main OADAClient class
*/
export declare class OADAClient {
#private;
constructor({ domain, token, concurrency, userAgent, connection, timeouts, }: Config & {
timeouts?: HTTPTimeouts;
});
/**
* Repurpose a existing connection to OADA-compliant server with a new token
* @param token New token.
*/
clone(token: string): OADAClient;
/**
* Get the connection token
*/
getToken(): string;
/**
* Get the connection domain
*/
getDomain(): string;
/**
* Get the connection concurrency
*/
getConcurrency(): number;
/** Disconnect from server */
disconnect(): Promise<void>;
/** Wait for the connection to open */
awaitConnection(): Promise<void>;
/**
* Send GET request
* @param request request
*/
get(request: GETRequest): Promise<Response>;
/**
* Set up watch
*
* @param request watch request
*/
watch(request: WatchRequestTree): Promise<WatchResponse<ReadonlyArray<Readonly<Change>>>>;
watch(request: WatchRequestSingle): Promise<WatchResponse<Readonly<Change>>>;
/**
* Watch API for v2
*
* @deprecated
*/
watch(request: WatchRequestTreeOld | WatchRequestSingleOld): Promise<string>;
unwatch(requestId: string): Promise<Response>;
/**
* Send PUT request
* @param request PUT request
*/
put(request: PUTRequest): Promise<Response>;
/**
* Send POST request
* @param request PUT request
*/
post(request: POSTRequest): Promise<Response>;
/**
* Send HEAD request
* @param request HEAD request
*/
head(request: HEADRequest): Promise<Response>;
/**
* Send DELETE request
* @param request DELETE request
*/
delete(request: DELETERequest): Promise<Response>;
/**
* Ensure a particular path with tree exists
* @param request ENSURERequest
*/
ensure(request: ENSURERequest): Promise<Response>;
}