UNPKG

@glimmer/di

Version:

Dependency injection support for Glimmer applications.

297 lines (264 loc) 10 kB
define('@glimmer/di', ['exports'], function (exports) { 'use strict'; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Container = function () { function Container(registry) { var resolver = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; _classCallCheck(this, Container); this._registry = registry; this._resolver = resolver; this._lookups = {}; this._factoryDefinitionLookups = {}; } Container.prototype.factoryFor = function factoryFor(specifier) { var factoryDefinition = this._factoryDefinitionLookups[specifier]; if (!factoryDefinition) { if (this._resolver) { factoryDefinition = this._resolver.retrieve(specifier); } if (!factoryDefinition) { factoryDefinition = this._registry.registration(specifier); } if (factoryDefinition) { this._factoryDefinitionLookups[specifier] = factoryDefinition; } } if (!factoryDefinition) { return; } return this.buildFactory(specifier, factoryDefinition); }; Container.prototype.lookup = function lookup(specifier) { var singleton = this._registry.registeredOption(specifier, 'singleton') !== false; if (singleton) { var lookup = this._lookups[specifier]; if (lookup) { return lookup.instance; } } var factory = this.factoryFor(specifier); if (!factory) { return; } if (this._registry.registeredOption(specifier, 'instantiate') === false) { return factory.class; } var instance = factory.create(); if (singleton && instance) { this._lookups[specifier] = { factory: factory, instance: instance }; } return instance; }; Container.prototype.defaultInjections = function defaultInjections(specifier) { return {}; }; Container.prototype.teardown = function teardown() { var specifiers = Object.keys(this._lookups); for (var i = 0; i < specifiers.length; i++) { var specifier = specifiers[i]; var _lookups$specifier = this._lookups[specifier], factory = _lookups$specifier.factory, instance = _lookups$specifier.instance; factory.teardown(instance); } }; Container.prototype.defaultTeardown = function defaultTeardown(instance) {}; Container.prototype.buildInjections = function buildInjections(specifier) { var hash = this.defaultInjections(specifier); var injections = this._registry.registeredInjections(specifier); var injection = void 0; for (var i = 0; i < injections.length; i++) { injection = injections[i]; hash[injection.property] = this.lookup(injection.source); } return hash; }; Container.prototype.buildFactory = function buildFactory(specifier, factoryDefinition) { var _this = this; var injections = this.buildInjections(specifier); return { class: factoryDefinition, teardown: function (instance) { if (factoryDefinition.teardown) { factoryDefinition.teardown(instance); } else { _this.defaultTeardown(instance); } }, create: function (options) { var mergedOptions = Object.assign({}, injections, options); return factoryDefinition.create(mergedOptions); } }; }; return Container; }(); function _classCallCheck$1(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Registry = function () { function Registry(options) { _classCallCheck$1(this, Registry); this._registrations = {}; this._registeredOptions = {}; this._registeredInjections = {}; if (options && options.fallback) { this._fallback = options.fallback; } } Registry.prototype.register = function register(specifier, factoryDefinition, options) { this._registrations[specifier] = factoryDefinition; if (options) { this._registeredOptions[specifier] = options; } }; Registry.prototype.registration = function registration(specifier) { var registration = this._registrations[specifier]; if (registration === undefined && this._fallback) { registration = this._fallback.registration(specifier); } return registration; }; Registry.prototype.unregister = function unregister(specifier) { delete this._registrations[specifier]; delete this._registeredOptions[specifier]; delete this._registeredInjections[specifier]; }; Registry.prototype.registerOption = function registerOption(specifier, option, value) { var options = this._registeredOptions[specifier]; if (!options) { options = {}; this._registeredOptions[specifier] = options; } options[option] = value; }; Registry.prototype.registeredOption = function registeredOption(specifier, option) { var result = void 0; var options = this.registeredOptions(specifier); if (options) { result = options[option]; } if (result === undefined && this._fallback !== undefined) { result = this._fallback.registeredOption(specifier, option); } return result; }; Registry.prototype.registeredOptions = function registeredOptions(specifier) { var options = this._registeredOptions[specifier]; if (options === undefined) { var type = specifier.split(':')[0]; options = this._registeredOptions[type]; } return options; }; Registry.prototype.unregisterOption = function unregisterOption(specifier, option) { var options = this._registeredOptions[specifier]; if (options) { delete options[option]; } }; Registry.prototype.registerInjection = function registerInjection(specifier, property, source) { var injections = this._registeredInjections[specifier]; if (injections === undefined) { this._registeredInjections[specifier] = injections = []; } injections.push({ property: property, source: source }); }; Registry.prototype.registeredInjections = function registeredInjections(specifier) { var type = specifier.split(':')[0]; var injections = this._fallback ? this._fallback.registeredInjections(specifier) : []; Array.prototype.push.apply(injections, this._registeredInjections[type]); Array.prototype.push.apply(injections, this._registeredInjections[specifier]); return injections; }; return Registry; }(); // TODO - use symbol var OWNER = '__owner__'; function getOwner(object) { return object[OWNER]; } function setOwner(object, owner) { object[OWNER] = owner; } function isSpecifierStringAbsolute(specifier) { var split = specifier.split(':'); var type = split[0]; var path = split[1]; return !!(type && path && path.indexOf('/') === 0 && path.split('/').length > 3); } function isSpecifierObjectAbsolute(specifier) { return specifier.rootName !== undefined && specifier.collection !== undefined && specifier.name !== undefined && specifier.type !== undefined; } function serializeSpecifier(specifier) { var type = specifier.type; var path = serializeSpecifierPath(specifier); if (path) { return type + ':' + path; } else { return type; } } function serializeSpecifierPath(specifier) { var path = []; if (specifier.rootName) { path.push(specifier.rootName); } if (specifier.collection) { path.push(specifier.collection); } if (specifier.namespace) { path.push(specifier.namespace); } if (specifier.name) { path.push(specifier.name); } if (path.length > 0) { var fullPath = path.join('/'); if (isSpecifierObjectAbsolute(specifier)) { fullPath = '/' + fullPath; } return fullPath; } } function deserializeSpecifier(specifier) { var obj = {}; if (specifier.indexOf(':') > -1) { var split = specifier.split(':'); var type = split[0]; var path = split[1]; obj.type = type; var pathSegments = void 0; if (path.indexOf('/') === 0) { pathSegments = path.substr(1).split('/'); if (path.substr(1).startsWith('@')) { obj.rootName = pathSegments.shift() + '/' + pathSegments.shift(); } else { obj.rootName = pathSegments.shift(); } obj.collection = pathSegments.shift(); } else { pathSegments = path.split('/'); } if (pathSegments.length > 0) { obj.name = pathSegments.pop(); if (pathSegments.length > 0) { obj.namespace = pathSegments.join('/'); } } } else { obj.type = specifier; } return obj; } exports.Container = Container; exports.Registry = Registry; exports.getOwner = getOwner; exports.setOwner = setOwner; exports.OWNER = OWNER; exports.isSpecifierStringAbsolute = isSpecifierStringAbsolute; exports.isSpecifierObjectAbsolute = isSpecifierObjectAbsolute; exports.serializeSpecifier = serializeSpecifier; exports.deserializeSpecifier = deserializeSpecifier; Object.defineProperty(exports, '__esModule', { value: true }); });