@holochain/client
Version:
A JavaScript client for the Holochain Conductor API
114 lines (113 loc) • 3.41 kB
JavaScript
const ERROR_TYPE = "error";
export const DEFAULT_TIMEOUT = 60000;
/**
* Take a Requester function which deals with tagged requests and responses,
* and return a Requester which deals only with the inner data types, also
* with the optional Transformer applied to further modify the input and output.
*
* @public
*/
export const requesterTransformer = (requester, tag, transform = identityTransformer) => async (req, timeout) => {
const transformedInput = await transform.input(req);
const input = { type: tag, data: transformedInput };
const response = await requester(input, timeout);
return transform.output(response.data);
};
const identity = (x) => x;
const identityTransformer = {
input: identity,
output: identity,
};
/**
* 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 = (response) => {
if (response.type === ERROR_TYPE) {
const errorName = response.data.type;
const error = new HolochainError(errorName, response.data.data);
return Promise.reject(error);
}
else {
return Promise.resolve(response);
}
};
export const promiseTimeout = (promise, tag, ms) => {
let id;
const timeout = new Promise((_, reject) => {
id = setTimeout(() => reject(new Error(`Request timed out in ${ms} ms: ${tag}`)), ms);
});
return new Promise((res, rej) => Promise.race([promise, timeout])
.then((a) => {
clearTimeout(id);
return res(a);
})
.catch((e) => {
clearTimeout(id);
return rej(e);
}));
};
const CLONE_ID_DELIMITER = ".";
/**
* Check if a cell's role name is a valid clone id.
*
* @param roleName - The role name to check.
*
* @public
*/
export const isCloneId = (roleName) => roleName.includes(CLONE_ID_DELIMITER);
/**
* Parse a clone id and get the role name part of it.
*
* @param roleName - The role name to parse.
* @public
*/
export const getBaseRoleNameFromCloneId = (roleName) => {
if (!isCloneId(roleName)) {
throw new HolochainError("MissingCloneIdDelimiter", `invalid clone id - no clone id delimiter found in role name ${roleName}`);
}
return roleName.split(CLONE_ID_DELIMITER)[0];
};
/**
* Identifier of a clone cell, composed of the DNA's role id and the index
* of the clone, starting at 0.
*
* Example: `profiles.0`
*
* @public
*/
export class CloneId {
roleName;
index;
constructor(roleName, index) {
this.roleName = roleName;
this.index = index;
}
/**
* Parse a role id of a clone cell to obtain a clone id instance.
* @param roleName - Role id to parse.
* @returns A clone id instance.
*/
static fromRoleName(roleName) {
const parts = roleName.split(CLONE_ID_DELIMITER);
if (parts.length !== 2) {
throw new HolochainError("MalformedCloneId", `clone id must consist of 'role_id.clone_index', but got ${roleName}`);
}
return new CloneId(parts[0], parseInt(parts[1]));
}
toString() {
return `${this.roleName}${CLONE_ID_DELIMITER}${this.index}`;
}
getBaseRoleName() {
return this.roleName;
}
}