nativescript
Version:
Command-line interface for building NativeScript projects
190 lines (189 loc) • 7.53 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.cache = cache;
exports.memoize = memoize;
exports.invokeBefore = invokeBefore;
exports.invokeInit = invokeInit;
exports.exported = exported;
exports.performanceLog = performanceLog;
exports.deprecated = deprecated;
const constants_1 = require("../constants");
const yok_1 = require("./yok");
function cache() {
return (target, propertyKey, descriptor) => {
let result;
const propName = descriptor.value ? "value" : "get";
const originalValue = descriptor[propName];
descriptor[propName] = function (...args) {
const propertyName = `__isCalled_${propertyKey}__`;
if (this && !this[propertyName]) {
this[propertyName] = true;
result = originalValue.apply(this, args);
}
return result;
};
return descriptor;
};
}
let memoizeIDCounter = 0;
function memoize(options) {
return (target, propertyKey, descriptor) => {
const DEBUG = false;
const memoizeID = memoizeIDCounter++;
const valueOrGet = descriptor.value ? "value" : "get";
const originalMethod = descriptor[valueOrGet];
descriptor[valueOrGet] = function (...args) {
const cacheMapName = `__memoize_cache_map_${memoizeID}`;
DEBUG && console.log(options);
let hashKey;
if (options.hashFn) {
DEBUG && console.log({ args });
hashKey = options.hashFn.apply(this, args);
}
else {
hashKey = `__memoize_cache_value_${memoizeID}`;
}
DEBUG &&
console.log({
cacheMapName,
hashKey,
});
if (!this.hasOwnProperty(cacheMapName)) {
DEBUG && console.log("NO CACHE MAP YET, CREATING ONE NOW");
Object.defineProperty(this, cacheMapName, {
configurable: false,
enumerable: false,
writable: false,
value: new Map(),
});
}
const cacheMap = this[cacheMapName];
DEBUG &&
console.log({
cacheMap,
});
if (cacheMap.has(hashKey)) {
DEBUG && console.log("CACHE HIT");
return cacheMap.get(hashKey);
}
DEBUG && console.log("CACHE MISS");
const result = originalMethod.apply(this, args);
let shouldCache = true;
if (options.shouldCache) {
shouldCache = options.shouldCache.call(this, result);
}
DEBUG && console.log("GOT BACK SHOULDCACHE", shouldCache);
if (shouldCache) {
DEBUG && console.log("CACHING NOW");
cacheMap.set(hashKey, result);
}
DEBUG && console.log("RETURNING", result);
return result;
};
return descriptor;
};
}
function invokeBefore(methodName, methodArgs) {
return (target, propertyKey, descriptor) => {
const originalValue = descriptor.value;
descriptor.value = async function (...args) {
await target[methodName].apply(this, methodArgs);
return originalValue.apply(this, args);
};
return descriptor;
};
}
function invokeInit() {
return invokeBefore("init");
}
function exported(moduleName) {
return (target, propertyKey, descriptor) => {
yok_1.injector.publicApi.__modules__[moduleName] =
yok_1.injector.publicApi.__modules__[moduleName] || {};
yok_1.injector.publicApi.__modules__[moduleName][propertyKey] = (...args) => {
const originalModule = yok_1.injector.resolve(moduleName), originalMethod = originalModule[propertyKey], result = originalMethod.apply(originalModule, args);
return result;
};
return descriptor;
};
}
function performanceLog(localInjector) {
localInjector = localInjector || yok_1.injector;
return function (target, propertyKey, descriptor) {
const originalMethod = descriptor.value;
const className = target.constructor.name;
const trackName = `${className}${constants_1.AnalyticsEventLabelDelimiter}${propertyKey}`;
const performanceService = localInjector.resolve("performanceService");
const functionWrapper = {
[originalMethod.name]: function (...args) {
const start = performanceService.now();
const result = originalMethod.apply(this, args);
const resolvedPromise = Promise.resolve(result);
let end;
if (resolvedPromise !== result) {
end = performanceService.now();
performanceService.processExecutionData(trackName, start, end, args);
}
else {
resolvedPromise
.then(() => {
end = performanceService.now();
performanceService.processExecutionData(trackName, start, end, args);
})
.catch((err) => {
end = performanceService.now();
performanceService.processExecutionData(trackName, start, end, args);
});
}
return result;
},
};
descriptor.value = functionWrapper[originalMethod.name];
descriptor.value.toString = () => {
return originalMethod.toString();
};
return descriptor;
};
}
function deprecated(additionalInfo, localInjector) {
const isDeprecatedMessage = " is deprecated.";
return (target, key, descriptor) => {
localInjector = localInjector || yok_1.injector;
additionalInfo = additionalInfo || "";
const $logger = localInjector.resolve("logger");
if (descriptor) {
if (descriptor.value) {
const originalMethod = descriptor.value;
descriptor.value = function (...args) {
$logger.warn(`${key.toString()}${isDeprecatedMessage} ${additionalInfo}`);
return originalMethod.apply(this, args);
};
return descriptor;
}
else {
if (descriptor.set) {
const originalSetter = descriptor.set;
descriptor.set = function (...args) {
$logger.warn(`${key.toString()}${isDeprecatedMessage} ${additionalInfo}`);
originalSetter.apply(this, args);
};
}
if (descriptor.get) {
const originalGetter = descriptor.get;
descriptor.get = function (...args) {
$logger.warn(`${key.toString()}${isDeprecatedMessage} ${additionalInfo}`);
return originalGetter.apply(this, args);
};
}
return descriptor;
}
}
else {
$logger.warn(`${(target &&
(target.name ||
(target.constructor && target.constructor.name))) ||
target}${isDeprecatedMessage} ${additionalInfo}`);
return target;
}
};
}