index.cjs 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. var __defProp = Object.defineProperty;
  2. var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
  3. var __getOwnPropNames = Object.getOwnPropertyNames;
  4. var __hasOwnProp = Object.prototype.hasOwnProperty;
  5. var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
  6. var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
  7. var __export = (target, all) => {
  8. for (var name in all)
  9. __defProp(target, name, { get: all[name], enumerable: true });
  10. };
  11. var __copyProps = (to, from, except, desc) => {
  12. if (from && typeof from === "object" || typeof from === "function") {
  13. for (let key of __getOwnPropNames(from))
  14. if (!__hasOwnProp.call(to, key) && key !== except)
  15. __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  16. }
  17. return to;
  18. };
  19. var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
  20. var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
  21. // src/index.js
  22. var index_exports = {};
  23. __export(index_exports, {
  24. SERVICE_CLASS_NAME: () => SERVICE_CLASS_NAME,
  25. Service: () => Service,
  26. ServiceContainer: () => ServiceContainer
  27. });
  28. module.exports = __toCommonJS(index_exports);
  29. // src/errors/invalid-argument-error.js
  30. var import_js_format = require("@e22m4u/js-format");
  31. var _InvalidArgumentError = class _InvalidArgumentError extends import_js_format.Errorf {
  32. };
  33. __name(_InvalidArgumentError, "InvalidArgumentError");
  34. var InvalidArgumentError = _InvalidArgumentError;
  35. // src/service-container.js
  36. var _ServiceContainer = class _ServiceContainer {
  37. /**
  38. * Services map.
  39. *
  40. * @type {Map<any, any>}
  41. * @private
  42. */
  43. _services = /* @__PURE__ */ new Map();
  44. /**
  45. * Parent container.
  46. *
  47. * @type {ServiceContainer}
  48. * @private
  49. */
  50. _parent;
  51. /**
  52. * Constructor.
  53. *
  54. * @param {ServiceContainer|undefined} parent
  55. */
  56. constructor(parent = void 0) {
  57. if (parent != null) {
  58. if (!(parent instanceof _ServiceContainer))
  59. throw new InvalidArgumentError(
  60. 'The provided parameter "parent" of ServicesContainer.constructor must be an instance ServiceContainer, but %v given.',
  61. parent
  62. );
  63. this._parent = parent;
  64. }
  65. }
  66. /**
  67. * Получить существующий или новый экземпляр.
  68. *
  69. * @param {*} ctor
  70. * @param {*} args
  71. * @return {*}
  72. */
  73. get(ctor, ...args) {
  74. if (!ctor || typeof ctor !== "function")
  75. throw new InvalidArgumentError(
  76. "The first argument of ServicesContainer.get must be a class constructor, but %v given.",
  77. ctor
  78. );
  79. if (!this._services.has(ctor) && this._parent && this._parent.has(ctor)) {
  80. return this._parent.get(ctor);
  81. }
  82. let service = this._services.get(ctor);
  83. if (!service) {
  84. const ctors = this._services.keys();
  85. const inheritedCtor = ctors.find((v) => v.prototype instanceof ctor);
  86. if (inheritedCtor) {
  87. service = this._services.get(inheritedCtor);
  88. ctor = inheritedCtor;
  89. }
  90. }
  91. if (!service || args.length) {
  92. service = Array.isArray(ctor.kinds) && ctor.kinds.includes(SERVICE_CLASS_NAME) ? new ctor(this, ...args) : new ctor(...args);
  93. this._services.set(ctor, service);
  94. } else if (typeof service === "function") {
  95. service = service();
  96. this._services.set(ctor, service);
  97. }
  98. return service;
  99. }
  100. /**
  101. * Проверка существования конструктора в контейнере.
  102. *
  103. * @param {*} ctor
  104. * @return {boolean}
  105. */
  106. has(ctor) {
  107. if (this._services.has(ctor)) return true;
  108. if (this._parent) return this._parent.has(ctor);
  109. const ctors = this._services.keys();
  110. const inheritedCtor = ctors.find((v) => v.prototype instanceof ctor);
  111. if (inheritedCtor) return true;
  112. return false;
  113. }
  114. /**
  115. * Добавить конструктор в контейнер.
  116. *
  117. * @param {*} ctor
  118. * @param {*} args
  119. * @return {this}
  120. */
  121. add(ctor, ...args) {
  122. if (!ctor || typeof ctor !== "function")
  123. throw new InvalidArgumentError(
  124. "The first argument of ServicesContainer.add must be a class constructor, but %v given.",
  125. ctor
  126. );
  127. const factory = /* @__PURE__ */ __name(() => Array.isArray(ctor.kinds) && ctor.kinds.includes(SERVICE_CLASS_NAME) ? new ctor(this, ...args) : new ctor(...args), "factory");
  128. this._services.set(ctor, factory);
  129. return this;
  130. }
  131. /**
  132. * Добавить конструктор и создать экземпляр.
  133. *
  134. * @param {*} ctor
  135. * @param {*} args
  136. * @return {this}
  137. */
  138. use(ctor, ...args) {
  139. if (!ctor || typeof ctor !== "function")
  140. throw new InvalidArgumentError(
  141. "The first argument of ServicesContainer.use must be a class constructor, but %v given.",
  142. ctor
  143. );
  144. const service = Array.isArray(ctor.kinds) && ctor.kinds.includes(SERVICE_CLASS_NAME) ? new ctor(this, ...args) : new ctor(...args);
  145. this._services.set(ctor, service);
  146. return this;
  147. }
  148. /**
  149. * Добавить конструктор и связанный экземпляр.
  150. *
  151. * @param {*} ctor
  152. * @param {*} service
  153. * @return {this}
  154. */
  155. set(ctor, service) {
  156. if (!ctor || typeof ctor !== "function")
  157. throw new InvalidArgumentError(
  158. "The first argument of ServicesContainer.set must be a class constructor, but %v given.",
  159. ctor
  160. );
  161. if (!service || typeof service !== "object" || Array.isArray(service))
  162. throw new InvalidArgumentError(
  163. "The second argument of ServicesContainer.set must be an Object, but %v given.",
  164. service
  165. );
  166. this._services.set(ctor, service);
  167. return this;
  168. }
  169. };
  170. __name(_ServiceContainer, "ServiceContainer");
  171. var ServiceContainer = _ServiceContainer;
  172. // src/service.js
  173. var SERVICE_CLASS_NAME = "Service";
  174. var _Service = class _Service {
  175. /**
  176. * Container.
  177. *
  178. * @type {ServiceContainer}
  179. */
  180. container;
  181. /**
  182. * Constructor.
  183. *
  184. * @param {ServiceContainer|undefined} container
  185. */
  186. constructor(container = void 0) {
  187. this.container = container instanceof ServiceContainer ? container : new ServiceContainer();
  188. }
  189. /**
  190. * Получить существующий или новый экземпляр.
  191. *
  192. * @param {*} ctor
  193. * @param {*} args
  194. * @return {*}
  195. */
  196. getService(ctor, ...args) {
  197. return this.container.get(ctor, ...args);
  198. }
  199. /**
  200. * Проверка существования конструктора в контейнере.
  201. *
  202. * @param {*} ctor
  203. * @return {boolean}
  204. */
  205. hasService(ctor) {
  206. return this.container.has(ctor);
  207. }
  208. /**
  209. * Добавить конструктор в контейнер.
  210. *
  211. * @param {*} ctor
  212. * @param {*} args
  213. * @return {this}
  214. */
  215. addService(ctor, ...args) {
  216. this.container.add(ctor, ...args);
  217. return this;
  218. }
  219. /**
  220. * Добавить конструктор и создать экземпляр.
  221. *
  222. * @param {*} ctor
  223. * @param {*} args
  224. * @return {this}
  225. */
  226. useService(ctor, ...args) {
  227. this.container.use(ctor, ...args);
  228. return this;
  229. }
  230. /**
  231. * Добавить конструктор и связанный экземпляр.
  232. *
  233. * @param {*} ctor
  234. * @param {*} service
  235. * @return {this}
  236. */
  237. setService(ctor, service) {
  238. this.container.set(ctor, service);
  239. return this;
  240. }
  241. };
  242. __name(_Service, "Service");
  243. /**
  244. * Kinds.
  245. *
  246. * @type {string[]}
  247. */
  248. __publicField(_Service, "kinds", [SERVICE_CLASS_NAME]);
  249. var Service = _Service;
  250. // Annotate the CommonJS export names for ESM import in node:
  251. 0 && (module.exports = {
  252. SERVICE_CLASS_NAME,
  253. Service,
  254. ServiceContainer
  255. });