@holochain/client
Advanced tools
Comparing version 0.14.1 to 0.15.0
@@ -28,3 +28,3 @@ import { CapSecret, GrantedFunctions } from "../../hdk/capabilities.js"; | ||
*/ | ||
static connect(url: string, defaultTimeout?: number): Promise<AdminWebsocket>; | ||
static connect(url: URL, defaultTimeout?: number): Promise<AdminWebsocket>; | ||
_requester<ReqI, ReqO, ResI, ResO>(tag: string, transformer?: Transformer<ReqI, ReqO, ResI, ResO>): (req: ReqI, timeout?: number | undefined) => Promise<ResO>; | ||
@@ -31,0 +31,0 @@ /** |
@@ -37,3 +37,3 @@ import { getLauncherEnvironment } from "../../environments/launcher.js"; | ||
if (env?.ADMIN_INTERFACE_PORT) { | ||
url = `ws://127.0.0.1:${env.ADMIN_INTERFACE_PORT}`; | ||
url = new URL(`ws://127.0.0.1:${env.ADMIN_INTERFACE_PORT}`); | ||
} | ||
@@ -40,0 +40,0 @@ const wsClient = await WsClient.connect(url); |
@@ -34,3 +34,3 @@ import Emittery, { UnsubscribeFunction } from "emittery"; | ||
*/ | ||
static connect(url: string, installed_app_id: InstalledAppId, defaultTimeout?: number): Promise<AppAgentWebsocket>; | ||
static connect(url: URL, installed_app_id: InstalledAppId, defaultTimeout?: number): Promise<AppAgentWebsocket>; | ||
/** | ||
@@ -37,0 +37,0 @@ * Get a cell id by its role name or clone id. |
@@ -26,3 +26,3 @@ import Emittery from "emittery"; | ||
*/ | ||
static connect(url: string, defaultTimeout?: number): Promise<AppWebsocket>; | ||
static connect(url: URL, defaultTimeout?: number): Promise<AppWebsocket>; | ||
_requester<ReqI, ReqO, ResI, ResO>(tag: string, transformer?: Transformer<ReqI, ReqO, ResI, ResO>): (req: ReqI, timeout?: number | undefined) => Promise<ResO>; | ||
@@ -29,0 +29,0 @@ /** |
@@ -38,3 +38,3 @@ import { hashZomeCall } from "@holochain/serialization"; | ||
if (env?.APP_INTERFACE_PORT) { | ||
url = `ws://127.0.0.1:${env.APP_INTERFACE_PORT}`; | ||
url = new URL(`ws://127.0.0.1:${env.APP_INTERFACE_PORT}`); | ||
} | ||
@@ -41,0 +41,0 @@ const wsClient = await WsClient.connect(url); |
/// <reference types="ws" /> | ||
import { decode } from "@msgpack/msgpack"; | ||
import Emittery from "emittery"; | ||
@@ -9,3 +8,3 @@ import IsoWebSocket from "isomorphic-ws"; | ||
* | ||
* Uses Holochain's websocket WireMessage for communication. | ||
* Uses Holochain's WireMessage for communication. | ||
* | ||
@@ -16,15 +15,15 @@ * @public | ||
socket: IsoWebSocket; | ||
pendingRequests: Record<number, { | ||
resolve: (msg: unknown) => ReturnType<typeof decode>; | ||
reject: (error: Error) => void; | ||
}>; | ||
url: URL | undefined; | ||
private pendingRequests; | ||
index: number; | ||
constructor(socket: IsoWebSocket); | ||
private connectRetries; | ||
constructor(socket: IsoWebSocket, url: URL); | ||
private setupSocket; | ||
/** | ||
* Instance factory for creating WsClients. | ||
* | ||
* @param url - The `ws://` URL to connect to. | ||
* @param url - The WebSocket URL to connect to. | ||
* @returns An new instance of the WsClient. | ||
*/ | ||
static connect(url: string): Promise<WsClient>; | ||
static connect(url: URL): Promise<WsClient>; | ||
/** | ||
@@ -42,3 +41,4 @@ * Sends data as a signal. | ||
*/ | ||
request<Req, Res>(request: Req): Promise<Res>; | ||
request<Response>(request: unknown): Promise<Response>; | ||
private sendMessage; | ||
private handleResponse; | ||
@@ -45,0 +45,0 @@ /** |
@@ -9,3 +9,3 @@ import { decode, encode } from "@msgpack/msgpack"; | ||
* | ||
* Uses Holochain's websocket WireMessage for communication. | ||
* Uses Holochain's WireMessage for communication. | ||
* | ||
@@ -16,10 +16,17 @@ * @public | ||
socket; | ||
url; | ||
pendingRequests; | ||
index; | ||
constructor(socket) { | ||
connectRetries; | ||
constructor(socket, url) { | ||
super(); | ||
this.socket = socket; | ||
this.url = url; | ||
this.pendingRequests = {}; | ||
this.index = 0; | ||
socket.onmessage = async (serializedMessage) => { | ||
this.connectRetries = 0; | ||
this.setupSocket(); | ||
} | ||
setupSocket() { | ||
this.socket.onmessage = async (serializedMessage) => { | ||
// If data is not a buffer (nodejs), it will be a blob (browser) | ||
@@ -69,3 +76,3 @@ let deserializedData; | ||
}; | ||
socket.onclose = (event) => { | ||
this.socket.onclose = (event) => { | ||
const pendingRequestIds = Object.keys(this.pendingRequests).map((id) => parseInt(id)); | ||
@@ -84,3 +91,3 @@ if (pendingRequestIds.length) { | ||
* | ||
* @param url - The `ws://` URL to connect to. | ||
* @param url - The WebSocket URL to connect to. | ||
* @returns An new instance of the WsClient. | ||
@@ -91,5 +98,2 @@ */ | ||
const socket = new IsoWebSocket(url); | ||
// make sure that there are no uncaught connection | ||
// errors because that causes nodejs thread to crash | ||
// with uncaught exception | ||
socket.onerror = () => { | ||
@@ -99,3 +103,3 @@ reject(new Error(`could not connect to holochain conductor, please check that a conductor service is running and available at ${url}`)); | ||
socket.onopen = () => { | ||
const client = new WsClient(socket); | ||
const client = new WsClient(socket, url); | ||
resolve(client); | ||
@@ -123,17 +127,24 @@ }; | ||
*/ | ||
request(request) { | ||
async request(request) { | ||
if (this.socket.readyState === this.socket.OPEN) { | ||
const id = this.index; | ||
const encodedMsg = encode({ | ||
id, | ||
type: "request", | ||
data: encode(request), | ||
}); | ||
const promise = new Promise((resolve, reject) => { | ||
this.pendingRequests[id] = { resolve, reject }; | ||
this.sendMessage(request, resolve, reject); | ||
}); | ||
this.socket.send(encodedMsg); | ||
this.index += 1; | ||
return promise; | ||
} | ||
else if (this.url) { | ||
const response = new Promise((resolve, reject) => { | ||
// typescript forgets in this promise scope that this.url is not undefined | ||
const socket = new IsoWebSocket(this.url); | ||
this.socket = socket; | ||
socket.onerror = () => { | ||
reject(new Error(`could not connect to Holochain conductor, please check that a conductor service is running and available at ${this.url}`)); | ||
}; | ||
socket.onopen = () => { | ||
this.sendMessage(request, resolve, reject); | ||
}; | ||
this.setupSocket(); | ||
}); | ||
return response; | ||
} | ||
else { | ||
@@ -143,2 +154,13 @@ return Promise.reject(new Error("Socket is not open")); | ||
} | ||
sendMessage(request, resolve, reject) { | ||
const id = this.index; | ||
const encodedMsg = encode({ | ||
id, | ||
type: "request", | ||
data: encode(request), | ||
}); | ||
this.socket.send(encodedMsg); | ||
this.pendingRequests[id] = { resolve, reject }; | ||
this.index += 1; | ||
} | ||
handleResponse(msg) { | ||
@@ -145,0 +167,0 @@ const id = msg.id; |
@@ -33,2 +33,10 @@ import { RoleName } from "../types.js"; | ||
export declare const requesterTransformer: <ReqI, ReqO, ResI, ResO>(requester: Requester<Tagged<ReqO>, Tagged<ResI>>, tag: string, transform?: Transformer<ReqI, ReqO, ResI, ResO>) => (req: ReqI, timeout?: number) => Promise<ResO>; | ||
/** | ||
* Error thrown when response from Holochain is an error. | ||
* | ||
* @public | ||
*/ | ||
export declare class HolochainError extends Error { | ||
constructor(name: string, message: string); | ||
} | ||
export declare const catchError: (res: any) => Promise<any>; | ||
@@ -35,0 +43,0 @@ export declare const promiseTimeout: (promise: Promise<unknown>, tag: string, ms: number) => Promise<unknown>; |
@@ -22,4 +22,23 @@ const ERROR_TYPE = "error"; | ||
}; | ||
/** | ||
* Error thrown when response from Holochain is an error. | ||
* | ||
* @public | ||
*/ | ||
export class HolochainError extends Error { | ||
constructor(name, message) { | ||
super(); | ||
this.name = name; | ||
this.message = message; | ||
} | ||
} | ||
// this determines the error format of all error responses | ||
export const catchError = (res) => { | ||
return res.type === ERROR_TYPE ? Promise.reject(res) : Promise.resolve(res); | ||
if (res.type === ERROR_TYPE) { | ||
const error = new HolochainError(res.data.type, res.data.data); | ||
return Promise.reject(error); | ||
} | ||
else { | ||
return Promise.resolve(res); | ||
} | ||
}; | ||
@@ -29,6 +48,3 @@ export const promiseTimeout = (promise, tag, ms) => { | ||
const timeout = new Promise((_, reject) => { | ||
id = setTimeout(() => { | ||
clearTimeout(id); | ||
reject(new Error(`Timed out in ${ms}ms: ${tag}`)); | ||
}, ms); | ||
id = setTimeout(() => reject(new Error(`Timed out in ${ms}ms: ${tag}`)), ms); | ||
}); | ||
@@ -35,0 +51,0 @@ return new Promise((res, rej) => { |
{ | ||
"name": "@holochain/client", | ||
"version": "0.14.1", | ||
"version": "0.15.0", | ||
"description": "A JavaScript client for the Holochain Conductor API", | ||
@@ -5,0 +5,0 @@ "author": "Holochain Foundation <info@holochain.org> (http://holochain.org)", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
100681
3273