index.cjs 8.1 KB

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