vmes-flowable
Version:
ceshibao
344 lines (276 loc) • 9.95 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global.didi = {})));
}(this, (function (exports) { 'use strict';
var CLASS_PATTERN = /^class /;
function isClass(fn) {
return CLASS_PATTERN.test(fn.toString());
}
function isArray(obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
}
function annotate() {
var args = Array.prototype.slice.call(arguments);
if (args.length === 1 && isArray(args[0])) {
args = args[0];
}
var fn = args.pop();
fn.$inject = args;
return fn;
}
// Current limitations:
// - can't put into "function arg" comments
// function /* (no parenthesis like this) */ (){}
// function abc( /* xx (no parenthesis like this) */ a, b) {}
//
// Just put the comment before function or inside:
// /* (((this is fine))) */ function(a, b) {}
// function abc(a) { /* (((this is fine))) */}
//
// - can't reliably auto-annotate constructor; we'll match the
// first constructor(...) pattern found which may be the one
// of a nested class, too.
var CONSTRUCTOR_ARGS = /constructor\s*[^(]*\(\s*([^)]*)\)/m;
var FN_ARGS = /^function\s*[^(]*\(\s*([^)]*)\)/m;
var FN_ARG = /\/\*([^*]*)\*\//m;
function parse(fn) {
if (typeof fn !== 'function') {
throw new Error('Cannot annotate "' + fn + '". Expected a function!');
}
var match = fn.toString().match(isClass(fn) ? CONSTRUCTOR_ARGS : FN_ARGS);
// may parse class without constructor
if (!match) {
return [];
}
return match[1] && match[1].split(',').map(function (arg) {
match = arg.match(FN_ARG);
return match ? match[1].trim() : arg.trim();
}) || [];
}
function Module() {
var providers = [];
this.factory = function (name, factory) {
providers.push([name, 'factory', factory]);
return this;
};
this.value = function (name, value) {
providers.push([name, 'value', value]);
return this;
};
this.type = function (name, type) {
providers.push([name, 'type', type]);
return this;
};
this.forEach = function (iterator) {
providers.forEach(iterator);
};
}
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
function Injector(modules, parent) {
parent = parent || {
get: function get(name, strict) {
currentlyResolving.push(name);
if (strict === false) {
return null;
} else {
throw error('No provider for "' + name + '"!');
}
}
};
var currentlyResolving = [];
var providers = this._providers = Object.create(parent._providers || null);
var instances = this._instances = Object.create(null);
var self = instances.injector = this;
var error = function error(msg) {
var stack = currentlyResolving.join(' -> ');
currentlyResolving.length = 0;
return new Error(stack ? msg + ' (Resolving: ' + stack + ')' : msg);
};
/**
* Return a named service.
*
* @param {String} name
* @param {Boolean} [strict=true] if false, resolve missing services to null
*
* @return {Object}
*/
var get = function get(name, strict) {
if (!providers[name] && name.indexOf('.') !== -1) {
var parts = name.split('.');
var pivot = get(parts.shift());
while (parts.length) {
pivot = pivot[parts.shift()];
}
return pivot;
}
if (hasProp(instances, name)) {
return instances[name];
}
if (hasProp(providers, name)) {
if (currentlyResolving.indexOf(name) !== -1) {
currentlyResolving.push(name);
throw error('Cannot resolve circular dependency!');
}
currentlyResolving.push(name);
instances[name] = providers[name][0](providers[name][1]);
currentlyResolving.pop();
return instances[name];
}
return parent.get(name, strict);
};
var fnDef = function fnDef(fn) {
var locals = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
if (typeof fn !== 'function') {
if (isArray(fn)) {
fn = annotate(fn.slice());
} else {
throw new Error('Cannot invoke "' + fn + '". Expected a function!');
}
}
var inject = fn.$inject || parse(fn);
var dependencies = inject.map(function (dep) {
if (hasProp(locals, dep)) {
return locals[dep];
} else {
return get(dep);
}
});
return {
fn: fn,
dependencies: dependencies
};
};
var instantiate = function instantiate(Type) {
var _fnDef = fnDef(Type),
dependencies = _fnDef.dependencies,
fn = _fnDef.fn;
return new (Function.prototype.bind.apply(fn, [null].concat(_toConsumableArray(dependencies))))();
};
var invoke = function invoke(func, context, locals) {
var _fnDef2 = fnDef(func, locals),
dependencies = _fnDef2.dependencies,
fn = _fnDef2.fn;
return fn.call.apply(fn, [context].concat(_toConsumableArray(dependencies)));
};
var createPrivateInjectorFactory = function createPrivateInjectorFactory(privateChildInjector) {
return annotate(function (key) {
return privateChildInjector.get(key);
});
};
var createChild = function createChild(modules, forceNewInstances) {
if (forceNewInstances && forceNewInstances.length) {
var fromParentModule = Object.create(null);
var matchedScopes = Object.create(null);
var privateInjectorsCache = [];
var privateChildInjectors = [];
var privateChildFactories = [];
var provider;
var cacheIdx;
var privateChildInjector;
var privateChildInjectorFactory;
for (var name in providers) {
provider = providers[name];
if (forceNewInstances.indexOf(name) !== -1) {
if (provider[2] === 'private') {
cacheIdx = privateInjectorsCache.indexOf(provider[3]);
if (cacheIdx === -1) {
privateChildInjector = provider[3].createChild([], forceNewInstances);
privateChildInjectorFactory = createPrivateInjectorFactory(privateChildInjector);
privateInjectorsCache.push(provider[3]);
privateChildInjectors.push(privateChildInjector);
privateChildFactories.push(privateChildInjectorFactory);
fromParentModule[name] = [privateChildInjectorFactory, name, 'private', privateChildInjector];
} else {
fromParentModule[name] = [privateChildFactories[cacheIdx], name, 'private', privateChildInjectors[cacheIdx]];
}
} else {
fromParentModule[name] = [provider[2], provider[1]];
}
matchedScopes[name] = true;
}
if ((provider[2] === 'factory' || provider[2] === 'type') && provider[1].$scope) {
/* jshint -W083 */
forceNewInstances.forEach(function (scope) {
if (provider[1].$scope.indexOf(scope) !== -1) {
fromParentModule[name] = [provider[2], provider[1]];
matchedScopes[scope] = true;
}
});
}
}
forceNewInstances.forEach(function (scope) {
if (!matchedScopes[scope]) {
throw new Error('No provider for "' + scope + '". Cannot use provider from the parent!');
}
});
modules.unshift(fromParentModule);
}
return new Injector(modules, self);
};
var factoryMap = {
factory: invoke,
type: instantiate,
value: function value(_value) {
return _value;
}
};
modules.forEach(function (module) {
function arrayUnwrap(type, value) {
if (type !== 'value' && isArray(value)) {
value = annotate(value.slice());
}
return value;
}
// TODO(vojta): handle wrong inputs (modules)
if (module instanceof Module) {
module.forEach(function (provider) {
var name = provider[0];
var type = provider[1];
var value = provider[2];
providers[name] = [factoryMap[type], arrayUnwrap(type, value), type];
});
} else if ((typeof module === 'undefined' ? 'undefined' : _typeof(module)) === 'object') {
if (module.__exports__) {
var clonedModule = Object.keys(module).reduce(function (m, key) {
if (key.substring(0, 2) !== '__') {
m[key] = module[key];
}
return m;
}, Object.create(null));
var privateInjector = new Injector((module.__modules__ || []).concat([clonedModule]), self);
var getFromPrivateInjector = annotate(function (key) {
return privateInjector.get(key);
});
module.__exports__.forEach(function (key) {
providers[key] = [getFromPrivateInjector, key, 'private', privateInjector];
});
} else {
Object.keys(module).forEach(function (name) {
if (module[name][2] === 'private') {
providers[name] = module[name];
return;
}
var type = module[name][0];
var value = module[name][1];
providers[name] = [factoryMap[type], arrayUnwrap(type, value), type];
});
}
}
});
// public API
this.get = get;
this.invoke = invoke;
this.instantiate = instantiate;
this.createChild = createChild;
}
// helpers /////////////////
function hasProp(obj, prop) {
return Object.hasOwnProperty.call(obj, prop);
}
exports.annotate = annotate;
exports.Module = Module;
exports.Injector = Injector;
Object.defineProperty(exports, '__esModule', { value: true });
})));