UNPKG

@ixily/activ

Version:

Alpha Capture Trade Idea Verification. Blockchain ownership proven trade ideas and strategies.

310 lines (293 loc) 7.93 kB
import { CacheStorageModule, ICacheVia, PreCacheModule, deserializeDataTool, serializeDataTool, } from '../../' import { contractDbVersion } from '../../../version-contract-db.json' const EXPIRATION_FOR_STRATEGY = 3600 * 24 * 100 // 100 days // structure of cache export const cachePlusUpsert = async ( preCacheId: string, key: string, data: string, expiration?: number, ): Promise<void> => { PreCacheModule.getSlots(preCacheId).add(key, data) try { await CacheStorageModule.addData(key, data, expiration) } catch (err) { await CacheStorageModule.updateData(key, data, expiration) } } export const cachePlusRemove = async (key: string) => { await CacheStorageModule.removeData(key) } export const cachePlusRetrieve = async <T>( preCacheId: string, key: string, ): Promise<string | undefined> => { // console.log('=-=-=-=-=-=-=-=-=-=-=-=-=-=-=') // console.log('=-=-=-=-=-=-=-=-=-=-=-=-=-=-=') // console.log('=-=-=-=-=-=-=-=-=-=-=-=-=-=-=') // console.log('=-=-=-=-=-=-=-=-=-=-=-=-=-=-=') const preCached = PreCacheModule.getSlots(preCacheId).get<string>(key) // console.log('preCached:') // console.log(preCached) if (preCached !== undefined) { return preCached } const data = await CacheStorageModule.getData(key) // console.log('data:') // console.log(data) return data as string | undefined // return (await CacheStorageModule.removeData(key)) as unknown as string } const getCacheKeyFromParameters = (parameters: any[]): string => { const serialized = serializeDataTool([contractDbVersion, ...parameters]) return serialized } const cacheIn = <U>( cachedFunctionName: string, argsToIndex: any[], ): ((cache: U) => Promise<void>) => { return async (cache: U): Promise<void> => { const cacheKey = getCacheKeyFromParameters([ cachedFunctionName, argsToIndex, ]) // console.log('cache:') // console.log(cache) const cacheValue = serializeDataTool(cache) // console.log('cacheValue:') // console.log(cacheValue) await cachePlusUpsert( 'strategyChain', cacheKey, cacheValue, EXPIRATION_FOR_STRATEGY, ) } } const cacheOut = <U>( cachedFunctionName: string, argsToIndex: any[], ): (() => Promise<U | undefined>) => { return async (): Promise<U | undefined> => { // console.log('=-=-=-=-=-=-=-=-=-=-=-=-=-=-=') // console.log('=-=-=-=-=-=-=-=-=-=-=-=-=-=-=') // console.log('=-=-=-=-=-=-=-=-=-=-=-=-=-=-=') // console.log('=-=-=-=-=-=-=-=-=-=-=-=-=-=-=') const cacheKey = getCacheKeyFromParameters([ cachedFunctionName, argsToIndex, ]) // console.log('cacheKey:') // console.log(cacheKey) const cacheValueStr = await cachePlusRetrieve('strategyChain', cacheKey) // console.log('cacheValueStr:') // console.log(cacheValueStr) if (cacheValueStr === undefined) { return undefined } const cacheValue = deserializeDataTool(cacheValueStr) as U return cacheValue } } // A => Arguments // U => Cache or Result const cacheVia = <U>( cachedFunctionName: string, argsToIndex: any[], ): ICacheVia<U> => { return { in: cacheIn<U>(cachedFunctionName, argsToIndex), out: cacheOut<U>(cachedFunctionName, argsToIndex), } } const recover = async <T>(via: ICacheVia<T>): Promise<T | undefined> => { return via.out() } // R => Result // C => Cache // U => Cache or Result const resultAfterStore = async <R, C, U extends R>( via: ICacheVia<U>, resultCache: | R | { result: R cache: C }, prevCached: any, ): Promise<R> => { // console.log('---------------TO CACHE----------------') // console.log('resultCache:') // console.log((resultCache as unknown as any).cache.cachedStrategy) // throw new Error('check') const resultAsCache = resultCache as { result: R cache: U } if ( resultAsCache.result !== undefined && resultAsCache.cache !== undefined ) { // console.log('resultAsCache.cache:') // console.log(resultAsCache.cache) const toGoCache = resultAsCache.cache if (serializeDataTool(toGoCache) !== serializeDataTool(prevCached)) { await via.in(toGoCache) } return resultAsCache.result as R } else { const resultAsResult = resultCache as R const toGoCache = resultAsResult as U if (serializeDataTool(toGoCache) !== serializeDataTool(prevCached)) { await via.in(toGoCache) } return resultAsResult as R } } // R => Result // C => Cache // U => Cache or Result const resultAfterStoreWithCache = async <R, C>( via: ICacheVia<C>, resultCache: { result: R cache: C }, prevCached: any, ): Promise<{ result: R cache: C }> => { // console.log('---------------TO CACHE----------------') // console.log('resultCache.cache:') // console.log(resultCache.cache) const toGoCache = resultCache.cache if (serializeDataTool(toGoCache) !== serializeDataTool(prevCached)) { await via.in(toGoCache) } return resultCache } // R => Result // C => Cache // A => Arguments const dynamicCached = async <R, C, A extends any[], U extends R>( functionCachedIdentifier: string, functionToBeCalled: (...args: A[number][any]) => Promise< | R | { result: R cache: C } >, argumentsForGettingData: A, argsToIndex: any[], ): Promise<R> => { const via = cacheVia<U>(functionCachedIdentifier, argsToIndex) const cached = await recover(via) // console.log('---------------FROM CACHE----------------') // console.log('cached:') // console.log(cached) // if (cached !== undefined) { // throw new Error('check') // } const argumentsForGettingDataPlusCache = [ ...argumentsForGettingData, cached, ] const resultCache = await functionToBeCalled( ...argumentsForGettingDataPlusCache, ) return resultAfterStore<R, C, U>(via, resultCache, cached) } // R => Result // C => Cache // A => Arguments const dynamicCachedWithCache = async <R, C, A extends any[]>( functionCachedIdentifier: string, functionToBeCalled: (...args: A[number][any]) => Promise<{ result: R cache: C }>, argumentsForGettingData: A, argsToIndex: any[], ): Promise<{ result: R cache: C }> => { const via = cacheVia<C>(functionCachedIdentifier, argsToIndex) const cached = await recover(via) // console.log('---------------FROM CACHE----------------') // console.log('cached:') // console.log(cached) // if (cached !== undefined) { // throw new Error('check') // } const argumentsForGettingDataPlusCache = [ ...argumentsForGettingData, cached, ] const resultCache = await functionToBeCalled( ...argumentsForGettingDataPlusCache, ) return resultAfterStoreWithCache<R, C>(via, resultCache, cached) } /* const STRIP_COMMENTS = /(\/\/.*$)|(\/\*[\s\S]*?\*\/)|(\s*=[^,\)]*(('(?:\\'|[^'\r\n])*')|("(?:\\"|[^"\r\n])*"))|(\s*=[^,\)]*))/gm const ARGUMENT_NAMES = /([^\s,]+)/g type FunctionType = (...args: any[]) => Promise<unknown> function getParamNames<F extends FunctionType>(func: F): string[] { const fnStr = func.toString().replace(STRIP_COMMENTS, '') let result: string[] | null = fnStr .slice(fnStr.indexOf('(') + 1, fnStr.indexOf(')')) .match(ARGUMENT_NAMES) if (result === null) result = [] as string[] return result as string[] } */ export const dynamicCachedFunction = <R, C, A extends any[]>( functionToBeCached: (...args: A[number][any]) => Promise< | R | { result: R cache: C } >, argsToIndex: any[], ): ((...args: A[number][any]) => Promise<R>) => { const fName = functionToBeCached.name return async (...args: A[number][any]): Promise<R> => { return dynamicCached(fName, functionToBeCached, args, argsToIndex) } } export const dynamicCachedFunctionWithCache = <R, C, A extends any[]>( functionToBeCached: (...args: A[number][any]) => Promise<{ result: R cache: C }>, argsToIndex: any[], ): ((...args: A[number][any]) => Promise<{ result: R cache: C }>) => { const fName = functionToBeCached.name return async ( ...args: A[number][any] ): Promise<{ result: R cache: C }> => { return dynamicCachedWithCache( fName, functionToBeCached, args, argsToIndex, ) } }