@jovian/type-tools
Version:
TypeTools is a Typescript library for providing extensible tooling runtime validations and type helpers.
198 lines • 9.53 kB
JavaScript
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.Derivables = exports.DerivablesExtensionData = exports.DerivablesSettings = void 0;
var type_tools_1 = require("./type-tools");
var data_importable_1 = require("./data-importable");
var properties_controller_1 = require("./properties-controller");
var class_lineage_1 = require("./class-lineage");
var context_1 = require("./context");
var common_iface_1 = require("./upstream/common.iface");
var DerivablesSettings = (function (_super) {
__extends(DerivablesSettings, _super);
function DerivablesSettings(init) {
var _this = _super.call(this, init) || this;
_this.extensionDerivables = DerivablesSettings.extensionDerivables;
if (init) {
Object.assign(_this, init);
}
return _this;
}
DerivablesSettings.extensionDerivables = 'Derivables';
return DerivablesSettings;
}(properties_controller_1.PropertiesControllerSettings));
exports.DerivablesSettings = DerivablesSettings;
var DerivablesExtensionData = (function () {
function DerivablesExtensionData() {
}
return DerivablesExtensionData;
}());
exports.DerivablesExtensionData = DerivablesExtensionData;
var Derivables = (function () {
function Derivables(settings) {
this.settings = (0, type_tools_1.settingsInitialize)(DerivablesSettings, settings);
}
Derivables.getExtensionData = function (target, settings) {
if (settings === void 0) { settings = DerivablesSettings; }
return type_tools_1.TypeToolsBase.getExtension(target, settings.extensionDerivables, settings);
};
Derivables.typeCheck = function (target, settings) {
if (settings === void 0) { settings = DerivablesSettings; }
return target && !!Derivables.getExtensionData(target, settings);
};
Derivables.implementOn = function (target, settings) {
if (settings === void 0) { settings = DerivablesSettings; }
if (!type_tools_1.TypeToolsBase.checkContext(Derivables)) {
return false;
}
if (!Derivables.getExtensionData(target, settings)) {
data_importable_1.DataImportable.implementOn(target);
properties_controller_1.PropertiesController.implementOn(target, settings);
var pcExtension = properties_controller_1.PropertiesController.getExtensionData(target, settings);
var extension_1 = { rubric: {}, triggers: {} };
pcExtension.onpropertychanges.push(function (propName, oldValue, newValue, immediate) {
var trigger = extension_1.triggers[propName];
if (!trigger) {
return;
}
for (var _i = 0, _a = trigger.list; _i < _a.length; _i++) {
var targetDerivedPropName = _a[_i];
var rubric = extension_1.rubric[targetDerivedPropName];
var result = void 0;
if (rubric.longHand) {
result = rubric.derive.apply(target);
}
else {
result = rubric.derive.apply(target, rubric.from.map(function (a) { return target[a]; }));
}
if (result !== undefined) {
target[targetDerivedPropName] = result;
}
}
});
type_tools_1.TypeToolsBase.addExtension(target, settings.extensionDerivables, extension_1);
}
return true;
};
Derivables.of = function (target, options, deriveRubric, settings) {
if (settings === void 0) { settings = DerivablesSettings; }
if (!Derivables.implementOn(target, settings)) {
return;
}
if (!options) {
options = {};
}
var extension = Derivables.getExtensionData(target, settings);
var type = class_lineage_1.ClassLineage.typeOf(target);
var cacheKeyPrefix = DerivablesSettings.extensionDerivables + '::' +
(context_1.Context.current ? (0, common_iface_1.typeFullName)(context_1.Context.current) + '::' : '');
var derivablesKeys = Object.keys(deriveRubric);
for (var _i = 0, derivablesKeys_1 = derivablesKeys; _i < derivablesKeys_1.length; _i++) {
var propName = derivablesKeys_1[_i];
var rubric = deriveRubric[propName];
var cached = type_tools_1.TypeToolsBase.typeCacheGet(type, cacheKeyPrefix + propName);
var from = void 0;
if (cached) {
from = cached.from;
}
else {
var longHand = rubric.derive ? true : false;
if (!longHand) {
from = (rubric + '').split('\n')[0].split('(')[1].split(')')[0].split(',').map(function (a) { return a.trim(); });
}
else {
from = Object.keys(rubric.from);
}
cached = { from: from, longHand: longHand };
var skel = type_tools_1.TypeToolsBase.getSkeleton(type);
for (var _a = 0, from_1 = from; _a < from_1.length; _a++) {
var prop = from_1[_a];
var msg = null;
if (skel[prop] === undefined) {
msg = "Derivable property '".concat(propName, "' cannot derive a non-member property '").concat(prop, "'");
}
if (prop === propName) {
msg = "Derivable property '".concat(propName, "' cannot be derived from itself.'");
}
if (msg) {
var e = new Error(msg);
if (context_1.Context.throwErrors) {
throw e;
}
from.length = 0;
break;
}
}
type_tools_1.TypeToolsBase.typeCacheSet(type, cacheKeyPrefix + propName, cached);
}
if (from.length > 0) {
extension.rubric[propName] = {
from: cached.from,
longHand: cached.longHand,
derive: cached.longHand ? rubric.derive : rubric
};
for (var _b = 0, from_2 = from; _b < from_2.length; _b++) {
var sourcePropName = from_2[_b];
var trigger = extension.triggers[sourcePropName];
if (!trigger) {
trigger = extension.triggers[sourcePropName] = { list: [], guard: {} };
}
if (!trigger.guard[propName]) {
trigger.list.push(propName);
trigger.guard[propName] = true;
}
}
}
}
var iteration = 0;
var changed = { __first: true };
while (Object.keys(changed).length > 0 && iteration < Derivables.maxInitialIterations) {
changed = {};
++iteration;
for (var _c = 0, derivablesKeys_2 = derivablesKeys; _c < derivablesKeys_2.length; _c++) {
var targetDerivedPropName = derivablesKeys_2[_c];
var rubric = extension.rubric[targetDerivedPropName];
if (!rubric) {
continue;
}
var result = void 0;
if (rubric.longHand) {
result = rubric.derive.apply(target);
}
else {
result = rubric.derive.apply(target, rubric.from.map(function (a) { return target[a]; }));
}
if (target[targetDerivedPropName] !== result) {
target[targetDerivedPropName] = result;
changed[targetDerivedPropName] = true;
}
}
}
if (iteration >= Derivables.maxInitialIterations) {
if (context_1.Context.throwErrors) {
throw new Error("Derivable keeps changing after ".concat(iteration, " iterations [keys=").concat(Object.keys(changed).join(', '), "]. "));
}
}
};
Derivables.prototype.getExtensionData = function (target) { return Derivables.getExtensionData(target, this.settings); };
Derivables.prototype.typeCheck = function (target) { return Derivables.typeCheck(target, this.settings); };
Derivables.prototype.implementOn = function (target) { return Derivables.implementOn(target, this.settings); };
Derivables.maxInitialIterations = 5;
return Derivables;
}());
exports.Derivables = Derivables;
//# sourceMappingURL=derivables.js.map
;