UNPKG

regard

Version:

Sugar-interface to access multiple data sources.

172 lines (123 loc) 4.43 kB
var _ = require('lodash'), Connector = require('./connector'), ConnectorsManager = require('./managers/connectors'), Endpoint = require('./endpoint'), EndpointsManager = require('./managers/endpoints'), Hash = require('object-hash'), Request = require('./request'), RequestsManager = require('./managers/requests'), Uuid = require('uuid'); exports = module.exports = Manager; function Manager(cacheMaxAge, cacheMax) { if (!(this instanceof Manager)) { return new Manager(cacheMaxAge, cacheMax); } this.api = _.bind(handleRequest, this, Connector.DEFAULT_HANDLER); this.api.$ = _.bind(handleEndpoint, this); this.api.$$ = _.bind(handleConnector, this); this.api.to = _.bind(handleEndpointFocused, this); if (_.isNumber(cacheMaxAge)) { RequestsManager.CACHE_MAXAGE = cacheMaxAge; } if (_.isNumber(cacheMax)) { RequestsManager.CACHE_MAX = cacheMax; } this.connectors = new ConnectorsManager; this.endpoints = new EndpointsManager; this.requests = new RequestsManager; } Manager.prototype.createConnector = function (ConnectorFactory, initArgs) { var connector = new ConnectorFactory(); connector.init.apply(connector, initArgs); if (!connector.handlers.has(Connector.DEFAULT_HANDLER)) { throw new Error('No default handler was found'); } this.connectors.add(connector); return connector; }; Manager.prototype.createEndpoint = function (key, initArgs) { var endpoint = new Endpoint(key); endpoint.init.apply(endpoint, initArgs); endpoint.parent = this.endpoints.getParent(key); endpoint.connector = this.connectors.resolve(endpoint); endpoint.root = _.isUndefined(endpoint.parent); if (_.isUndefined(endpoint.connector)) { throw new Error('No connector was found'); } endpoint.connector.onCreateEndpoint(endpoint); this.createEndpointApi(endpoint); this.endpoints.add(endpoint); return endpoint; }; Manager.prototype.createEndpointApi = function (endpoint) { var api = _.bind(handleRequest, this, Connector.DEFAULT_HANDLER, endpoint); api.$ = _.bind(handleEndpointNested, this, endpoint.key); _.forEach(endpoint.connector.handlers.data, function (value) { var key = value.key; if (key !== Connector.DEFAULT_HANDLER) { _.set(api, key, _.bind(handleRequest, this, key, endpoint)); } }, this); _.set(this.api, endpoint.keyDotted, api); return api; }; Manager.prototype.createRequest = function (endpoint, handler, initArgs) { var hash = Hash(_.toArray(arguments)), request = this.requests.get(hash); if (_.isObject(request)) { return request; } request = new Request(hash); request.init(endpoint, handler, initArgs); endpoint.connector.onCreateRequest(request); this.requests.add(request); return request; }; function handleConnector(connector) { if (_.isArray(connector)) { _.each(connector, _.flow(_.identity, _.bind(handleConnector, this))); return this.api; } if (_.isString(connector)) { connector = this.connectors.core(connector); } if (!_.isFunction(connector)) { throw new Error('A connector factory or a core connector name was expected'); } this.createConnector(connector, _.slice(arguments, 1)); return this.api; } function handleEndpoint(key) { if (!_.isString(key) || _.isEmpty(key)) { throw new Error('A name was expected'); } this.createEndpoint(key, _.slice(arguments, 1)); return this.api; } function handleEndpointNested(parent, key) { key = [parent, key].join('/'); return _.partial(handleEndpoint, key).apply(this, _.slice(arguments, 2)); } function handleEndpointFocused() { var key = Uuid.v4(); _.partial(handleEndpoint, key).apply(this, _.toArray(arguments)); return _.get(this.api, key); } function handleRequest(handler, endpoint) { if (_.isString(endpoint)) { var doubleDot = endpoint.lastIndexOf(':'); if (doubleDot > -1) { handler = endpoint.substring(doubleDot+1); endpoint = endpoint.substring(0, doubleDot); } endpoint = this.endpoints.get(endpoint); } if (_.isUndefined(endpoint) || !_.isObject(endpoint.connector)) { throw new Error('No endpoint was found'); } if (!endpoint.connector.handlers.has(handler)) { throw new Error('No handler was found'); } var request = this.createRequest(endpoint, handler, _.slice(arguments, 2)); return this.requests.prepare(request); }