UNPKG

ajsfw

Version:
556 lines (555 loc) 25.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var utils = require("ajsfw/utils"); var exceptions_1 = require("ajsfw/exceptions"); var AjsWebWorker_1 = require("./ajs-web-worker/AjsWebWorker"); var AjsWebWorker_2 = require("./ajs-web-worker/AjsWebWorker"); var RMIEndPoint_1 = require("./rmi/RMIEndPoint"); var RMIRouter_1 = require("./rmi/RMIRouter"); var ServiceContainerExistsAlreadyException = (function (_super) { __extends(ServiceContainerExistsAlreadyException, _super); function ServiceContainerExistsAlreadyException() { return _super !== null && _super.apply(this, arguments) || this; } return ServiceContainerExistsAlreadyException; }(exceptions_1.Exception)); exports.ServiceContainerExistsAlreadyException = ServiceContainerExistsAlreadyException; ; var ServiceContainerNotExistException = (function (_super) { __extends(ServiceContainerNotExistException, _super); function ServiceContainerNotExistException() { return _super !== null && _super.apply(this, arguments) || this; } return ServiceContainerNotExistException; }(exceptions_1.Exception)); exports.ServiceContainerNotExistException = ServiceContainerNotExistException; ; var FailedToLocateWebWorkerException = (function (_super) { __extends(FailedToLocateWebWorkerException, _super); function FailedToLocateWebWorkerException() { return _super !== null && _super.apply(this, arguments) || this; } return FailedToLocateWebWorkerException; }(exceptions_1.Exception)); exports.FailedToLocateWebWorkerException = FailedToLocateWebWorkerException; ; var ServiceManagerEndpointAssignedAlreadyException = (function (_super) { __extends(ServiceManagerEndpointAssignedAlreadyException, _super); function ServiceManagerEndpointAssignedAlreadyException() { return _super !== null && _super.apply(this, arguments) || this; } return ServiceManagerEndpointAssignedAlreadyException; }(exceptions_1.Exception)); exports.ServiceManagerEndpointAssignedAlreadyException = ServiceManagerEndpointAssignedAlreadyException; ; var ServiceManagerNotRegisteredWithTheWebWorkerException = (function (_super) { __extends(ServiceManagerNotRegisteredWithTheWebWorkerException, _super); function ServiceManagerNotRegisteredWithTheWebWorkerException() { return _super !== null && _super.apply(this, arguments) || this; } return ServiceManagerNotRegisteredWithTheWebWorkerException; }(exceptions_1.Exception)); exports.ServiceManagerNotRegisteredWithTheWebWorkerException = ServiceManagerNotRegisteredWithTheWebWorkerException; ; var FailedToLocateNamespaceInParentNamespaceException = (function (_super) { __extends(FailedToLocateNamespaceInParentNamespaceException, _super); function FailedToLocateNamespaceInParentNamespaceException() { return _super !== null && _super.apply(this, arguments) || this; } return FailedToLocateNamespaceInParentNamespaceException; }(exceptions_1.Exception)); exports.FailedToLocateNamespaceInParentNamespaceException = FailedToLocateNamespaceInParentNamespaceException; ; var ServiceManager = (function () { function ServiceManager(config) { var _this = this; this.__config = config || this.__defaultConfig(); this.__rmiRouter = new RMIRouter_1.RMIRouter(); this.__rmiRouter.addEndpointRegisteredListener(function (iface, endpointId) { return _this.__onRMIEndpointCreated(iface, endpointId); }); this.__workerUrl = this.__config.workerUrl; this.__workerLibraries = this.__config.workerLibraries; this.__localServiceContainer = { ajsWorkerInfo: { worker: null, webWokrerReadyResolver: null, webWorkerReadyRejector: null, serviceManagerId: 0 }, deployedNamespaces: [], deployedServices: [], instancedServices: [], namedServiceInstances: {} }; this.__serviceContainers = {}; this.__serviceContainers[this.__config.mainUiThreadServiceContainerName] = this.__localServiceContainer; this.__deployedServices = []; this.__deployedServicesMethods = []; } ServiceManager.prototype.createServiceContainer = function (name) { var _this = this; var scReadyPromise = new Promise(function (resolve, reject) { if (name in _this.__serviceContainers) { reject(new ServiceContainerExistsAlreadyException()); } var worker = new AjsWebWorker_2.AjsWebWorker(_this.__workerUrl, _this.__workerLibraries, _this.__workerCode); _this.__rmiRouter.addInterface(worker); _this.__serviceContainers[name] = { ajsWorkerInfo: { worker: worker, webWokrerReadyResolver: resolve, webWorkerReadyRejector: reject, serviceManagerId: -1 }, deployedNamespaces: [], deployedServices: [], instancedServices: [], namedServiceInstances: {} }; }); return scReadyPromise; }; ServiceManager.prototype.instantiateLocalNamedService = function (serviceName, service) { var ctorArgs = []; for (var _i = 2; _i < arguments.length; _i++) { ctorArgs[_i - 2] = arguments[_i]; } return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2]; }); }); }; ServiceManager.prototype.instantiateLocalService = function (service) { var ctorArgs = []; for (var _i = 1; _i < arguments.length; _i++) { ctorArgs[_i - 1] = arguments[_i]; } return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2]; }); }); }; ServiceManager.prototype.instantiateNamedService = function (serviceName, serviceContainerName, serviceCodeScope, service) { var ctorArgs = []; for (var _i = 4; _i < arguments.length; _i++) { ctorArgs[_i - 4] = arguments[_i]; } return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2, null]; }); }); }; ServiceManager.prototype.instantiateService = function (serviceContainerName, service) { var ctorArgs = []; for (var _i = 2; _i < arguments.length; _i++) { ctorArgs[_i - 2] = arguments[_i]; } return __awaiter(this, void 0, void 0, function () { var si, wi, className, serviceId; return __generator(this, function (_a) { switch (_a.label) { case 0: if (!(serviceContainerName in this.__serviceContainers)) { throw new ServiceContainerNotExistException(); } if (serviceContainerName === this.__config.mainUiThreadServiceContainerName) { return [2, this.instantiateLocalService.apply(this, [service].concat(ctorArgs))]; } si = this.__serviceContainers[serviceContainerName]; wi = si.ajsWorkerInfo; if (wi.serviceManagerId === -1) { throw new ServiceManagerNotRegisteredWithTheWebWorkerException(); } className = utils.getClassName(service); if (!(si.deployedServices.indexOf(className) === -1)) return [3, 2]; return [4, this.__deployServiceCode(serviceContainerName, service)]; case 1: _a.sent(); _a.label = 2; case 2: return [4, this.__instantiateService_call.apply(this, [wi.serviceManagerId, className].concat(ctorArgs))]; case 3: serviceId = _a.sent(); return [2, this.__createServiceProxy(service, serviceId)]; } }); }); }; ServiceManager.prototype.deployNamespace = function (serviceContainerName) { var namespaces = []; for (var _i = 1; _i < arguments.length; _i++) { namespaces[_i - 1] = arguments[_i]; } return __awaiter(this, void 0, void 0, function () { var deployAll, nsNames, parent, _i, namespaces_1, ns, found, key; return __generator(this, function (_a) { if (serviceContainerName === undefined || serviceContainerName === null || serviceContainerName === "" || namespaces.length === 0 || (namespaces.length === 1 && typeof (namespaces[0]) !== "object")) { return [2]; } deployAll = typeof (namespaces[namespaces.length - 1]) === "boolean" ? namespaces[namespaces.length - 1] : false; if (namespaces[namespaces.length - 1] === "boolean") { namespaces.splice(namespaces.length - 1, 1); } nsNames = []; parent = self; for (_i = 0, namespaces_1 = namespaces; _i < namespaces_1.length; _i++) { ns = namespaces_1[_i]; found = false; for (key in parent) { if (ns === parent[key]) { nsNames.push(key); parent = ns; found = true; break; } } if (!found) { throw new FailedToLocateNamespaceInParentNamespaceException(); } } console.log(nsNames); if (!deployAll) { this.__serializeNamespace(nsNames[namespaces.length - 1], namespaces[namespaces.length - 1]); return [2]; } return [2]; }); }); }; ServiceManager.prototype.__serializeNamespace = function (nsName, ns) { function serializeFunction(fn) { if (fn.toString().trim().substr(0, 5) === "class") { return fn.toString(); } var proto = Object.getPrototypeOf(fn); if (proto === null) { return fn.toString(); } return ""; } function replacer(key, value) { if (this[key] instanceof Function) { return serializeFunction(value); } if (this[key] instanceof Date) { } if (typeof (this[key]) === "object" && key !== "") { return; } return "<" + typeof (value) + ">" + value; } return JSON.stringify(ns, replacer, 2); }; ServiceManager.prototype.__deployServiceCode = function (serviceContainerName, service) { return __awaiter(this, void 0, void 0, function () { var wi, className, code, e_1; return __generator(this, function (_a) { switch (_a.label) { case 0: if (!(serviceContainerName in this.__serviceContainers)) { throw new ServiceContainerNotExistException(); } wi = this.__serviceContainers[serviceContainerName].ajsWorkerInfo; if (wi.serviceManagerId === -1) { throw new ServiceManagerNotRegisteredWithTheWebWorkerException(); } _a.label = 1; case 1: _a.trys.push([1, 3, , 4]); className = utils.getClassName(service); code = this.__serializeClass(service); return [4, this.__deployServiceCode_call(wi.serviceManagerId, className, code)]; case 2: _a.sent(); this.__serviceContainers[serviceContainerName].deployedServices.push(className); if (this.__deployedServices.indexOf(service) === -1) { this.__extractDeployedServiceMethods(service); this.__deployedServices.push(service); } console.log("Service '" + className + "' deployed to " + serviceContainerName + " (worker service manager id: " + wi.serviceManagerId + ")"); return [3, 4]; case 3: e_1 = _a.sent(); console.error(e_1); return [3, 4]; case 4: return [2]; } }); }); }; ServiceManager.prototype.__createServiceProxy = function (serviceCtor, serviceId) { var dsm = this.__getDeployedServiceMethods(serviceCtor); if (dsm === null) { return null; } var proxyClass = function ServiceProxy(rmiRouter, rmiServiceId) { this["__ajsRmiRouter"] = rmiRouter; this["__ajsRmiServiceId"] = rmiServiceId; }; proxyClass.prototype = serviceCtor.prototype; var proxy = new proxyClass(this.__rmiRouter, serviceId); for (var _i = 0, _a = dsm.methods; _i < _a.length; _i++) { var m = _a[_i]; var fndef = "return function " + m + "() {"; fndef += "var args = []; "; fndef += "for (var i = 0; i < arguments.length; i++) { args.push(arguments[i]); }; "; fndef += "return this.__ajsRmiRouter.makeCall.apply(this.__ajsRmiRouter, [this.__ajsRmiServiceId, \"" + m + "\"].concat(args))"; fndef += "}"; proxy[m] = (new Function(fndef))(); } return proxy; }; ServiceManager.prototype.testCall = function (rmiId, method) { var args = []; for (var _i = 2; _i < arguments.length; _i++) { args[_i - 2] = arguments[_i]; } return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2]; }); }); }; ServiceManager.prototype.__onRMIEndpointCreated = function (iface, endpointId) { return __awaiter(this, void 0, void 0, function () { var sc, wi; return __generator(this, function (_a) { sc = this.__getServiceContainerByWorker(iface); if (sc === null || sc.ajsWorkerInfo === null || sc.ajsWorkerInfo.worker === null) { throw new FailedToLocateWebWorkerException(); } wi = sc.ajsWorkerInfo; if (wi.serviceManagerId === -1) { wi.serviceManagerId = endpointId; wi.webWokrerReadyResolver(); wi.webWokrerReadyResolver = null; wi.webWorkerReadyRejector = null; } else { if (wi.webWorkerReadyRejector !== null) { wi.webWorkerReadyRejector(new ServiceManagerEndpointAssignedAlreadyException()); } } return [2]; }); }); }; ServiceManager.prototype.__getServiceContainerByWorker = function (ajsWorker) { for (var name_1 in this.__serviceContainers) { if (this.__serviceContainers.hasOwnProperty(name_1)) { if (this.__serviceContainers[name_1].ajsWorkerInfo && this.__serviceContainers[name_1].ajsWorkerInfo.worker === ajsWorker) { return this.__serviceContainers[name_1]; } } } return null; }; ServiceManager.prototype.__getDeployedServiceMethods = function (service) { if (this.__deployedServices.indexOf(service) === -1) { return null; } for (var _i = 0, _a = this.__deployedServicesMethods; _i < _a.length; _i++) { var dsm = _a[_i]; if (dsm.service === service) { return dsm; } } return null; }; ServiceManager.prototype.__extractDeployedServiceMethods = function (service) { if (this.__deployedServices.indexOf(service) !== -1) { return; } var methods = []; var current = service; while (current && current.prototype) { var props = Object.getOwnPropertyNames(current.prototype); for (var _i = 0, props_1 = props; _i < props_1.length; _i++) { var prop = props_1[_i]; if (prop === "constructor") { continue; } if (typeof (current.prototype[prop]) === "function" && methods.indexOf(prop) === -1) { methods.push(prop); continue; } } current = Object.getPrototypeOf(current); } this.__deployedServicesMethods.push({ service: service, methods: methods, }); }; ServiceManager.prototype.__serializeClass = function (obj) { if (typeof (obj) !== "function" || !obj.prototype) { return ""; } var out = ""; if (obj.prototype) { out += this.__serializeClass(Object.getPrototypeOf(obj)); } out += this.__buildClassString(obj); return out; }; ServiceManager.prototype.__buildClassString = function (obj) { var classString = obj.toString(); var className = utils.getClassName(obj); var constructorArgs = classString.substring(classString.indexOf("(") + 1, classString.indexOf("{") - 1); constructorArgs = constructorArgs.substr(0, constructorArgs.lastIndexOf(")")); var constructorBody = classString.substring(classString.indexOf("{") + 1, classString.lastIndexOf("}")); var superClassName = ""; if (obj.prototype) { var proto = Object.getPrototypeOf(obj); superClassName = utils.getClassName(proto); } var out = "this." + className + " = this." + className + " || (function("; if (superClassName) { out += "_super"; } out += ") {\n"; if (superClassName) { out += " __extends(" + className + ", _super)\n\n"; } out += " function " + className + " (" + constructorArgs + ") { " + constructorBody + "}\n\n"; if (obj.prototype) { for (var key in obj.prototype) { if (obj.prototype.hasOwnProperty(key) && typeof (obj.prototype[key]) === "function") { out += " " + className + ".prototype." + key + " = " + obj.prototype[key].toString() + "\n\n"; } } } out += " return " + className + ";\n"; out += "})("; if (superClassName) { out += "this." + superClassName; } out += ");\n\n"; return out; }; ServiceManager.prototype.__defaultConfig = function () { return { workerUrl: "/js/ajs.wworker.js", workerLibraries: ["/js/ajs.lib.js"], mainUiThreadServiceContainerName: "main-ui-thread" }; }; ServiceManager.prototype.__deployServiceCode_call = function (remoteServiceManager, serviceName, serviceCode) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2, this.__rmiRouter.makeCall(remoteServiceManager, "deployServiceCode", serviceName, serviceCode)]; }); }); }; ServiceManager.prototype.__instantiateService_call = function (remoteServiceManager, serviceName, ctorArgs) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2, this.__rmiRouter.makeCall.apply(this.__rmiRouter, [remoteServiceManager, "instantiateService", serviceName].concat(ctorArgs))]; }); }); }; ServiceManager.prototype.__workerCode = function () { var servicesSourceCodeScopes = {}; var FailedToDelpoyTheServiceException = (function (_super) { __extends(FailedToDelpoyTheServiceException, _super); function FailedToDelpoyTheServiceException() { return _super !== null && _super.apply(this, arguments) || this; } return FailedToDelpoyTheServiceException; }(exceptions_1.Exception)); ; var ServiceNameDoesNotMatchCodeException = (function (_super) { __extends(ServiceNameDoesNotMatchCodeException, _super); function ServiceNameDoesNotMatchCodeException() { return _super !== null && _super.apply(this, arguments) || this; } return ServiceNameDoesNotMatchCodeException; }(exceptions_1.Exception)); ; var ServiceManager = (function () { function ServiceManager() { this.__selfRMIEndpointId = -1; } Object.defineProperty(ServiceManager.prototype, "selfRMIEndpointId", { set: function (value) { if (this.__selfRMIEndpointId === -1) { this.__selfRMIEndpointId = value; } }, enumerable: true, configurable: true }); ServiceManager.prototype.deployServiceCode = function (serviceName, serviceCode) { return __awaiter(this, void 0, void 0, function () { function deploy() { try { eval(serviceCode); } catch (e) { throw new FailedToDelpoyTheServiceException(e); } } return __generator(this, function (_a) { deploy.apply(servicesSourceCodeScopes); console.log(servicesSourceCodeScopes); if (!(serviceName in servicesSourceCodeScopes)) { throw new ServiceNameDoesNotMatchCodeException(); } return [2]; }); }); }; ServiceManager.prototype.instantiateService = function (serviceName) { var ctorArgs = []; for (var _i = 1; _i < arguments.length; _i++) { ctorArgs[_i - 1] = arguments[_i]; } return __awaiter(this, void 0, void 0, function () { function instantiate() { var ctor = servicesSourceCodeScopes[serviceName]; return new (ctor.bind.apply(ctor, [null].concat(ctorArgs))); } var instance, rmiep; return __generator(this, function (_a) { switch (_a.label) { case 0: console.log(serviceName); instance = instantiate(); rmiep = new RMIEndPoint_1.RMIEndpoint(AjsWebWorker_1.ajsWorkerInstance, instance); return [4, rmiep.waitRegistered()]; case 1: _a.sent(); return [2, rmiep.endPointId]; } }); }); }; return ServiceManager; }()); function createServiceManager() { return __awaiter(this, void 0, void 0, function () { var serviceManager, rmiep; return __generator(this, function (_a) { switch (_a.label) { case 0: serviceManager = new ServiceManager(); rmiep = new RMIEndPoint_1.RMIEndpoint(AjsWebWorker_1.ajsWorkerInstance, serviceManager); return [4, rmiep.waitRegistered()]; case 1: _a.sent(); serviceManager.selfRMIEndpointId = rmiep.endPointId; return [2]; } }); }); } return createServiceManager; }; return ServiceManager; }()); exports.ServiceManager = ServiceManager;