UNPKG

@graphql-hive/core

Version:
176 lines (175 loc) • 5.28 kB
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(); } }