@web5/agent
Version:
161 lines • 7.47 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import { Jws } from '@tbd54566975/dwn-sdk-js';
import { utils as didUtils } from '@web5/dids';
import { ReadableWebToNodeStream } from 'readable-web-to-node-stream';
import { DateSort, DwnInterfaceName, DwnMethodName, Message } from '@tbd54566975/dwn-sdk-js';
export function blobToIsomorphicNodeReadable(blob) {
return webReadableToIsomorphicNodeReadable(blob.stream());
}
export function getDwnServiceEndpointUrls(didUri, dereferencer) {
return __awaiter(this, void 0, void 0, function* () {
// Attempt to dereference the DID service with ID fragment #dwn.
const dereferencingResult = yield dereferencer.dereference(`${didUri}#dwn`);
if (dereferencingResult.dereferencingMetadata.error) {
throw new Error(`Failed to dereference '${didUri}#dwn': ${dereferencingResult.dereferencingMetadata.error}`);
}
if (didUtils.isDwnDidService(dereferencingResult.contentStream)) {
const { serviceEndpoint } = dereferencingResult.contentStream;
const serviceEndpointUrls = typeof serviceEndpoint === 'string'
// If the service endpoint is a string, format it as a single-element array.
? [serviceEndpoint]
: Array.isArray(serviceEndpoint) && serviceEndpoint.every(endpoint => typeof endpoint === 'string')
// If the service endpoint is an array of strings, use it as is.
? serviceEndpoint
// If the service endpoint is neither a string nor an array of strings, return an empty array.
: [];
if (serviceEndpointUrls.length > 0) {
return serviceEndpointUrls;
}
}
// If the DID service with ID fragment #dwn was not found or is not valid, return an empty array.
return [];
});
}
export function getRecordAuthor(record) {
return Message.getAuthor(record);
}
/**
* Get the `protocolRole` string from the signature payload of the given RecordsWriteMessage or RecordsDeleteMessage.
*/
export function getRecordProtocolRole(message) {
const signaturePayload = Jws.decodePlainObjectPayload(message.authorization.signature);
return signaturePayload === null || signaturePayload === void 0 ? void 0 : signaturePayload.protocolRole;
}
export function isRecordsWrite(obj) {
// Validate that the given value is an object.
if (!obj || typeof obj !== 'object' || obj === null)
return false;
// Validate that the object has the necessary properties of RecordsWrite.
return ('message' in obj && typeof obj.message === 'object' && obj.message !== null &&
'descriptor' in obj.message && typeof obj.message.descriptor === 'object' && obj.message.descriptor !== null &&
'interface' in obj.message.descriptor && obj.message.descriptor.interface === DwnInterfaceName.Records &&
'method' in obj.message.descriptor && obj.message.descriptor.method === DwnMethodName.Write);
}
/**
* Get the CID of the given RecordsWriteMessage.
*/
export function getRecordMessageCid(message) {
return Message.getCid(message);
}
/**
* Get the pagination cursor for the given RecordsWriteMessage and DateSort.
*
* @param message The RecordsWriteMessage for which to get the pagination cursor.
* @param dateSort The date sort that will be used in the query or subscription to which the cursor will be applied.
*/
export function getPaginationCursor(message, dateSort) {
return __awaiter(this, void 0, void 0, function* () {
const value = dateSort === DateSort.CreatedAscending || dateSort === DateSort.CreatedDescending ?
message.descriptor.dateCreated : message.descriptor.datePublished;
if (value === undefined) {
throw new Error('The dateCreated or datePublished property is missing from the record descriptor.');
}
return {
messageCid: yield getRecordMessageCid(message),
value
};
});
}
export function webReadableToIsomorphicNodeReadable(webReadable) {
return new ReadableWebToNodeStream(webReadable);
}
/**
* Polling function with interval, TTL accepting a custom fetch function
* @template T - the return you expect from the fetcher
* @param fetchFunction an http fetch function
* @param [interval=3000] how frequently to poll
* @param [ttl=300_000] how long until polling stops
* @returns T - the result of fetch
*/
export function pollWithTtl(fetchFunction, interval = 3000, ttl = 300000, abortSignal) {
const endTime = Date.now() + ttl;
let timeoutId = null;
let isPolling = true;
return new Promise((resolve, reject) => {
if (abortSignal) {
abortSignal.addEventListener('abort', () => {
isPolling = false;
if (timeoutId !== null) {
clearTimeout(timeoutId);
}
console.log('Polling aborted by user');
resolve(null);
});
}
function poll() {
return __awaiter(this, void 0, void 0, function* () {
if (!isPolling)
return;
const remainingTime = endTime - Date.now();
if (remainingTime <= 0) {
isPolling = false;
console.log('Polling stopped: TTL reached');
resolve(null);
return;
}
console.log(`Polling... (Remaining time: ${Math.ceil(remainingTime / 1000)}s)`);
try {
const response = yield fetchFunction();
if (response.ok) {
isPolling = false;
if (timeoutId !== null) {
clearTimeout(timeoutId);
}
console.log('Polling stopped: Success condition met');
resolve(response);
return;
}
}
catch (error) {
console.error('Error fetching data:', error);
reject(error);
}
if (isPolling) {
timeoutId = setTimeout(poll, interval);
}
});
}
poll();
});
}
/** Concatenates a base URL and a path ensuring that there is exactly one slash between them */
export function concatenateUrl(baseUrl, path) {
// Remove trailing slash from baseUrl if it exists
if (baseUrl.endsWith('/')) {
baseUrl = baseUrl.slice(0, -1);
}
// Remove leading slash from path if it exists
if (path.startsWith('/')) {
path = path.slice(1);
}
return `${baseUrl}/${path}`;
}
//# sourceMappingURL=utils.js.map