ajsfw
Version:
Ajs Framework
556 lines (555 loc) • 25.7 kB
JavaScript
"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;