Guest User

Untitled

a guest
Jun 19th, 2018
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.08 KB | None | 0 0
  1. // -----------------------------------------------------------------------------
  2. // generic namespace generator the constructor should declare private functions
  3. // and variables and return public api, the module is created when all dependecies
  4. // are resolved (all modules are created)
  5. //
  6. // @param namespace dot separated namespace that will be added to window object
  7. // @param dependencies array of string (dependencies) can be empty array
  8. // @param constructor function that should return public module API
  9. //
  10. // usage:
  11. // module('app.projects', ['app.helpers'], function(helpers) {
  12. // console.log(app.helpers === helpers);
  13. // helpers.log('hello');
  14. // return {
  15. // foo: function() {
  16. // helpers.log('foo');
  17. // }
  18. // };
  19. // });
  20. // module('app.helpers', [], function() {
  21. // return {
  22. // log: function(msg) {
  23. // console.log(msg);
  24. // }
  25. // };
  26. // });
  27. // -----------------------------------------------------------------------------
  28. var module = (function() {
  29. // to keep track of dependecies, real objects are nested in window
  30. var modules = {};
  31.  
  32. // ---------------------------------------------------------------------------
  33. function init(module) {
  34. var dependecies = module.dependencies.map(function(name) {
  35. if (!modules[name]) {
  36. throw new Error('module ' + name + ' not defined when init ' + module.name);
  37. }
  38. return modules[name].module;
  39. });
  40. Object.assign(module.module, module.constructor.apply(null, dependecies));
  41. }
  42. // ---------------------------------------------------------------------------
  43. function concat(array) {
  44. array = array.slice()
  45. if (array.length > 1) {
  46. var last = array.pop();
  47. return array.join(', ') + ' and ' + last;
  48. } else {
  49. return array[0];
  50. }
  51. }
  52. // ---------------------------------------------------------------------------
  53. return function module(namespace, dependencies, constructor) {
  54. var names = namespace.split('.');
  55. var current = window;
  56. names.forEach(function(name) {
  57. if (!current[name]) {
  58. current[name] = {};
  59. }
  60. current = current[name];
  61. });
  62. if (modules[namespace]) {
  63. throw new Error('Module ' + namespace + ' already defined');
  64. }
  65. var module = modules[namespace] = {
  66. name: namespace,
  67. module: current,
  68. dependencies: dependencies,
  69. constructor: constructor
  70. };
  71. // if dependencies not resolved
  72. if (dependencies.length) {
  73. // are all dependentant modules loaded?
  74. var foundDepenencies = dependencies.filter(function(dependency) {
  75. return modules[dependency];
  76. });
  77. if (foundDepenencies.length === dependencies.length) {
  78. init(module);
  79. }
  80. } else {
  81. // no depeendecies
  82. init(module);
  83. }
  84. var modulesWithDependecies = Object.keys(modules).filter(function(name) {
  85. var module = modules[name];
  86. // don't process self and modules that don't have dependencies,
  87. // those was already loaded
  88. return Object.keys(module.dependencies).length;
  89. });
  90.  
  91. modulesWithDependecies.filter(function(name) {
  92. return name !== namespace;
  93. }).forEach(function(name) {
  94. var module = modules[name];
  95. var dependats = module.dependencies;
  96. var resolved = dependats.filter(function(key) {
  97. return modules[key];
  98. });
  99. // init modules that have resolved dependecies
  100. if (resolved.length == dependats.length) {
  101. init(module);
  102. } else {
  103. // find mutual dependecies
  104. if (dependats.length) {
  105. var mutualDependant = modulesWithDependecies.filter(function(searchName) {
  106. var searchModule = modules[searchName];
  107. return Object.keys(searchModule.dependencies).indexOf(name) !== -1;
  108. });
  109. if (mutualDependant.length) {
  110. var brokenModules = mutualDependant.concat([name]);
  111. // this will show error in toaster and log in server because of window
  112. // error handler in error.js
  113. throw new Error(concat(brokenModules) + ' have mutual dependecy');
  114. }
  115. }
  116. }
  117. });
  118. };
  119. })();
Add Comment
Please, Sign In to add comment