@graphql-hive/core
Version:
176 lines (175 loc) • 5.28 kB
JavaScript
import { crypto, TextEncoder } from '@whatwg-node/fetch';
import { hiveClientSymbol } from './client.js';
async function digest(algo, output, data) {
const buffer = await crypto.subtle.digest(algo, new TextEncoder().encode(data));
if (output === 'hex') {
return arrayBufferToHEX(buffer);
}
return arrayBufferToBase64(buffer);
}
function arrayBufferToHEX(buffer) {
return Array.prototype.map
.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2))
.join('');
}
function arrayBufferToBase64(buffer) {
return btoa(String.fromCharCode.apply(null, new Uint8Array(buffer)));
}
export function createHash(algo) {
let str = '';
return {
update(data) {
str += data;
return this;
},
async digest(output) {
return digest(algo, output, str);
},
};
}
export function memo(fn, cacheKeyFn) {
let memoizedResult = null;
let memoizedKey = null;
return (arg) => {
const currentKey = cacheKeyFn(arg);
if (memoizedKey === currentKey) {
return memoizedResult;
}
memoizedKey = currentKey;
memoizedResult = fn(arg);
return memoizedResult;
};
}
export function isAsyncIterable(value) {
return (value === null || value === void 0 ? void 0 : value[Symbol.asyncIterator]) != null;
}
export function cache(fn, cacheKeyFn, cacheMap) {
return async (arg, arg2) => {
const key = await cacheKeyFn(arg, arg2);
const cachedValue = await cacheMap.get(key);
if (cachedValue !== null && typeof cachedValue !== 'undefined') {
return {
key,
value: cachedValue,
cacheHit: true,
};
}
const value = fn(arg, arg2);
cacheMap.set(key, value);
return {
key,
value,
cacheHit: false,
};
};
}
export async function cacheDocumentKey(doc, variables) {
const hasher = createHash('SHA-1').update(JSON.stringify(doc));
if (variables) {
hasher.update(JSON.stringify(variables, (_, value) => {
if ((value && typeof value === 'object' && Object.keys(value).length) ||
(Array.isArray(value) && value.length)) {
return value;
}
return '';
}));
}
return hasher.digest('hex');
}
const HR_TO_NS = 1e9;
const NS_TO_MS = 1e6;
function deltaFrom(startedAt) {
const endedAt = performance.now();
const ns = Math.round(((endedAt - startedAt) * HR_TO_NS) / 1000);
return {
ns,
get ms() {
return ns / NS_TO_MS;
},
};
}
export function measureDuration() {
const startAt = performance.now();
return function end() {
return deltaFrom(startAt).ns;
};
}
export function addProperty(key, value, obj) {
if (value === null || typeof value === 'undefined') {
return obj;
}
return Object.assign(Object.assign({}, obj), { [key]: value });
}
export function isHiveClient(clientOrOptions) {
return hiveClientSymbol in clientOrOptions;
}
export function logIf(condition, message, logFn) {
if (condition) {
logFn(message);
}
}
export function joinUrl(url, subdirectory) {
const normalizedUrl = url.endsWith('/') ? url.slice(0, -1) : url;
const normalizedSubdirectory = subdirectory.startsWith('/')
? subdirectory.slice(1)
: subdirectory;
return normalizedUrl + '/' + normalizedSubdirectory;
}
const hiveSymbol = Symbol('hive-logger');
function printPath(path) {
if (path.length) {
return path + ' ';
}
return path;
}
export function createHiveLogger(baseLogger, prefix, debug = true) {
const context = Object.assign({ path: '', logger: baseLogger, debug }, baseLogger === null || baseLogger === void 0 ? void 0 : baseLogger[hiveSymbol]);
context.path = context.path + prefix;
const { logger, path } = context;
return {
[hiveSymbol]: context,
info: (message) => {
logger.info(printPath(path) + message);
},
error: (error, ...data) => {
if (error.stack) {
const pth = printPath(path);
for (const stack of error.stack.split('\n')) {
logger.error(pth + stack);
}
}
else {
logger.error(printPath(path) + String(error), ...data);
}
},
debug: (message) => {
if (!context.debug) {
return;
}
const msg = printPath(path) + message;
if (!logger.debug) {
logger.info(msg);
return;
}
logger.debug(msg);
},
};
}
export function isLegacyAccessToken(accessToken) {
if (!accessToken.startsWith('hvo1/') &&
!accessToken.startsWith('hvp1/') &&
!accessToken.startsWith('hvu1/')) {
return true;
}
return false;
}
export async function loadCircuitBreaker(success, error) {
const packageName = 'opossum';
try {
const module = await import(packageName);
success(module.default);
}
catch (err) {
error();
}
}