UNPKG

@harishreddym/baqend

Version:

Baqend JavaScript SDK

217 lines (182 loc) 6.93 kB
'use strict'; const message = require('./message'); const metamodel = require('./metamodel'); const util = require('./util'); const deprecated = require('./util/deprecated'); const Connector = require('./connector/Connector'); const EntityManager = require('./EntityManager'); const CONNECTED = Symbol('Connected'); /** * @alias EntityManagerFactory * @extends util.Lockable */ class EntityManagerFactory extends util.Lockable { /** * Creates a new EntityManagerFactory connected to the given destination * @param {string|Object} [options] The destination to connect with, or an options object * @param {string} [options.host] The destination to connect with * @param {number} [options.port=80|443] The optional destination port to connect with * @param {boolean} [options.secure=false] <code>true</code> To use a secure ssl encrypted connection * @param {string} [options.basePath="/v1"] The base path of the api * @param {Object} [options.schema=null] The serialized schema as json used to initialize the metamodel * @param {util.TokenStorage} [options.tokenStorage] The tokenStorage which should be used by this emf * @param {util.TokenStorageFactory} [options.tokenStorageFactory] The tokenStorage factory implementation which * should be used for token storage * @param {number} [options.staleness=60] The maximum staleness of objects that are acceptable while reading cached * data */ constructor(options) { super(); const opt = Object(options) instanceof String ? { host: options } : options || {}; /** @type connector.Connector */ this.connection = null; /** @type metamodel.Metamodel */ this.metamodel = this.createMetamodel(); /** @type util.Code */ this.code = new util.Code(this.metamodel, this); /** @type util.TokenStorageFactory */ this.tokenStorageFactory = util.TokenStorage.WEB_STORAGE || util.TokenStorage.GLOBAL; this.configure(opt); let isReady = true; let ready = new Promise((success) => { this[CONNECTED] = success; }); if (opt.host) { this.connect(opt.host, opt.port, opt.secure, opt.basePath); } else { isReady = false; } if (!this.tokenStorage) { isReady = false; ready = ready .then(() => this.tokenStorageFactory.create(this.connection.origin)) .then((tokenStorage) => { this.tokenStorage = tokenStorage; }); } if (opt.schema) { this.connectData = opt; this.metamodel.init(opt.schema); } else { isReady = false; ready = ready.then(() => { const msg = new message.Connect(); msg.withCredentials = true; // used for registered devices if (this.staleness === 0) { msg.noCache(); } return this.send(msg); }).then((response) => { this.connectData = response.entity; if (this.staleness === undefined) { this.staleness = this.connectData.bloomFilterRefresh || 60; } if (!this.metamodel.isInitialized) { this.metamodel.init(this.connectData.schema); } this.tokenStorage.update(this.connectData.token); }); } if (!isReady) { this.withLock(() => ready, true); } } /** * Apply additional configurations to this EntityManagerFactory * @param {Object} options The additional configuration options * @param {util.TokenStorage} [options.tokenStorage] The tokenStorage which should be used by this emf * @param {util.TokenStorageFactory} [options.tokenStorageFactory] The tokenStorage factory implementation which * should be used for token storage * @param {number} [options.staleness=60] The maximum staleness of objects that are acceptable while reading cached * data, <code>0</code> to always bypass the browser cache * @return {void} */ configure(options) { if (this.connection) { throw new Error('The EntityManagerFactory can only be configured before is is connected.'); } if (options.tokenStorage) { /** @type util.TokenStorage */ this.tokenStorage = options.tokenStorage; } if (options.tokenStorageFactory) { this.tokenStorageFactory = options.tokenStorageFactory; } if (options.staleness !== undefined) { /** @type number */ this.staleness = options.staleness; } } /** * Connects this EntityManager to the given destination * @param {string} hostOrApp The host or the app name to connect with * @param {number} [port=80|443] The port to connect to * @param {boolean} [secure=false] <code>true</code> To use a secure connection * @param {string} [basePath="/v1"] The base path of the api * @return {Promise<this>} */ connect(hostOrApp, port, secure, basePath) { if (this.connection) { throw new Error('The EntityManagerFactory is already connected.'); } if (Object(port) instanceof Boolean) { return this.connect(hostOrApp, 0, port, secure); } this.connection = Connector.create(hostOrApp, port, secure, basePath); this[CONNECTED](); return this.ready(); } /** * Connects this EntityManager to the given destination * @param {string} hostOrApp The host or the app name to connect with * @param {boolean} [secure=false] <code>true</code> To use a secure connection * @return {Promise<this>} * @name connect * @memberOf EntityManagerFactory.prototype * @method */ /** * Creates a new Metamodel instance, which is not connected * @return {metamodel.Metamodel} A new Metamodel instance */ createMetamodel() { return new metamodel.Metamodel(this); } /** * Create a new application-managed EntityManager. * * @param {boolean=} useSharedTokenStorage The token storage to persist the authorization token, or * <code>true</code> To use the shared token storage of the emf. * <code>false</code> To use a instance based storage. * * @return {EntityManager} a new entityManager */ createEntityManager(useSharedTokenStorage) { const em = new EntityManager(this); if (this.isReady) { em.connected( this.connection, this.connectData, useSharedTokenStorage ? this.tokenStorage : new util.TokenStorage(this.connection.origin) ); } else { em.withLock(() => this.ready().then(() => { em.connected( this.connection, this.connectData, useSharedTokenStorage ? this.tokenStorage : new util.TokenStorage(this.connection.origin) ); }), true); } return em; } send(msg) { if (!msg.tokenStorage) { msg.tokenStorage = this.tokenStorage; } return this.connection.send(msg); } } deprecated(EntityManagerFactory.prototype, '_connector', 'connection'); deprecated(EntityManagerFactory.prototype, '_connected', CONNECTED); module.exports = EntityManagerFactory;