UNPKG

@jovian/type-tools

Version:

TypeTools is a Typescript library for providing extensible tooling runtime validations and type helpers.

198 lines 9.53 kB
"use strict"; 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