e22m4u 1 год назад
Родитель
Сommit
9aacc66da0
3 измененных файлов с 234 добавлено и 6 удалено
  1. 6 0
      build-cjs.js
  2. 227 5
      dist/cjs/index.cjs
  3. 1 1
      package.json

+ 6 - 0
build-cjs.js

@@ -1,4 +1,5 @@
 import * as esbuild from 'esbuild';
+import packageJson from './package.json' with {type: 'json'};
 
 await esbuild.build({
   entryPoints: ['src/index.js'],
@@ -6,5 +7,10 @@ await esbuild.build({
   format: 'cjs',
   platform: 'node',
   target: ['node12'],
+  bundle: true,
   keepNames: true,
+  external: [
+    ...Object.keys(packageJson.peerDependencies || {}),
+    ...Object.keys(packageJson.dependencies || {}),
+  ],
 });

+ 227 - 5
dist/cjs/index.cjs

@@ -2,6 +2,12 @@ var __defProp = Object.defineProperty;
 var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
 var __getOwnPropNames = Object.getOwnPropertyNames;
 var __hasOwnProp = Object.prototype.hasOwnProperty;
+var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
+var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
+var __export = (target, all) => {
+  for (var name in all)
+    __defProp(target, name, { get: all[name], enumerable: true });
+};
 var __copyProps = (to, from, except, desc) => {
   if (from && typeof from === "object" || typeof from === "function") {
     for (let key of __getOwnPropNames(from))
@@ -10,14 +16,230 @@ var __copyProps = (to, from, except, desc) => {
   }
   return to;
 };
-var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
 var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
+var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
+
+// src/index.js
 var src_exports = {};
+__export(src_exports, {
+  Service: () => Service,
+  ServiceContainer: () => ServiceContainer
+});
 module.exports = __toCommonJS(src_exports);
-__reExport(src_exports, require("./service.js"), module.exports);
-__reExport(src_exports, require("./service-container.js"), module.exports);
+
+// src/errors/invalid-argument-error.js
+var import_js_format = require("@e22m4u/js-format");
+var _InvalidArgumentError = class _InvalidArgumentError extends import_js_format.Errorf {
+};
+__name(_InvalidArgumentError, "InvalidArgumentError");
+var InvalidArgumentError = _InvalidArgumentError;
+
+// src/service-container.js
+var _ServiceContainer = class _ServiceContainer {
+  /**
+   * Services map.
+   *
+   * @type {Map<any, any>}
+   * @private
+   */
+  _services = /* @__PURE__ */ new Map();
+  /**
+   * Parent container.
+   *
+   * @type {ServiceContainer}
+   * @private
+   */
+  _parent;
+  /**
+   * Constructor.
+   *
+   * @param {ServiceContainer|undefined} parent
+   */
+  constructor(parent = void 0) {
+    if (parent != null) {
+      if (!(parent instanceof _ServiceContainer))
+        throw new InvalidArgumentError(
+          'The provided parameter "parent" of ServicesContainer.constructor must be an instance ServiceContainer, but %v given.',
+          parent
+        );
+      this._parent = parent;
+    }
+  }
+  /**
+   * Получить существующий или новый экземпляр.
+   *
+   * @param {*} ctor
+   * @param {*} args
+   * @return {*}
+   */
+  get(ctor, ...args) {
+    if (!ctor || typeof ctor !== "function")
+      throw new InvalidArgumentError(
+        "The first argument of ServicesContainer.get must be a class constructor, but %v given.",
+        ctor
+      );
+    if (!this._services.has(ctor) && this._parent && this._parent.has(ctor)) {
+      return this._parent.get(ctor);
+    }
+    let service = this._services.get(ctor);
+    if (!service || args.length) {
+      service = ctor.kind === Service.kind ? new ctor(this, ...args) : new ctor(...args);
+      this._services.set(ctor, service);
+    } else if (typeof service === "function") {
+      service = service();
+      this._services.set(ctor, service);
+    }
+    return service;
+  }
+  /**
+   * Проверка существования конструктора в контейнере.
+   *
+   * @param {*} ctor
+   * @return {boolean}
+   */
+  has(ctor) {
+    if (this._services.has(ctor)) return true;
+    if (this._parent) return this._parent.has(ctor);
+    return false;
+  }
+  /**
+   * Добавить конструктор в контейнер.
+   *
+   * @param {*} ctor
+   * @param {*} args
+   * @return {this}
+   */
+  add(ctor, ...args) {
+    if (!ctor || typeof ctor !== "function")
+      throw new InvalidArgumentError(
+        "The first argument of ServicesContainer.add must be a class constructor, but %v given.",
+        ctor
+      );
+    const factory = /* @__PURE__ */ __name(() => ctor.kind === Service.kind ? new ctor(this, ...args) : new ctor(...args), "factory");
+    this._services.set(ctor, factory);
+    return this;
+  }
+  /**
+   * Добавить конструктор и создать экземпляр.
+   *
+   * @param {*} ctor
+   * @param {*} args
+   * @return {this}
+   */
+  use(ctor, ...args) {
+    if (!ctor || typeof ctor !== "function")
+      throw new InvalidArgumentError(
+        "The first argument of ServicesContainer.use must be a class constructor, but %v given.",
+        ctor
+      );
+    const service = ctor.kind === Service.kind ? new ctor(this, ...args) : new ctor(...args);
+    this._services.set(ctor, service);
+    return this;
+  }
+  /**
+   * Добавить конструктор и связанный экземпляр.
+   *
+   * @param {*} ctor
+   * @param {*} service
+   * @return {this}
+   */
+  set(ctor, service) {
+    if (!ctor || typeof ctor !== "function")
+      throw new InvalidArgumentError(
+        "The first argument of ServicesContainer.set must be a class constructor, but %v given.",
+        ctor
+      );
+    if (!service || typeof service !== "object" || Array.isArray(service))
+      throw new InvalidArgumentError(
+        "The second argument of ServicesContainer.set must be an Object, but %v given.",
+        service
+      );
+    this._services.set(ctor, service);
+    return this;
+  }
+};
+__name(_ServiceContainer, "ServiceContainer");
+var ServiceContainer = _ServiceContainer;
+
+// src/service.js
+var _Service = class _Service {
+  /**
+   * Container.
+   *
+   * @type {ServiceContainer}
+   */
+  container;
+  /**
+   * Constructor.
+   *
+   * @param {ServiceContainer|undefined} container
+   */
+  constructor(container = void 0) {
+    this.container = container instanceof ServiceContainer ? container : new ServiceContainer();
+  }
+  /**
+   * Получить существующий или новый экземпляр.
+   *
+   * @param {*} ctor
+   * @param {*} args
+   * @return {*}
+   */
+  getService(ctor, ...args) {
+    return this.container.get(ctor, ...args);
+  }
+  /**
+   * Проверка существования конструктора в контейнере.
+   *
+   * @param {*} ctor
+   * @return {boolean}
+   */
+  hasService(ctor) {
+    return this.container.has(ctor);
+  }
+  /**
+   * Добавить конструктор в контейнер.
+   *
+   * @param {*} ctor
+   * @param {*} args
+   * @return {this}
+   */
+  addService(ctor, ...args) {
+    this.container.add(ctor, ...args);
+    return this;
+  }
+  /**
+   * Добавить конструктор и создать экземпляр.
+   *
+   * @param {*} ctor
+   * @param {*} args
+   * @return {this}
+   */
+  useService(ctor, ...args) {
+    this.container.use(ctor, ...args);
+    return this;
+  }
+  /**
+   * Добавить конструктор и связанный экземпляр.
+   *
+   * @param {*} ctor
+   * @param {*} service
+   * @return {this}
+   */
+  setService(ctor, service) {
+    this.container.set(ctor, service);
+    return this;
+  }
+};
+__name(_Service, "Service");
+/**
+ * Kind.
+ *
+ * @type {string}
+ */
+__publicField(_Service, "kind", "Service");
+var Service = _Service;
 // Annotate the CommonJS export names for ESM import in node:
 0 && (module.exports = {
-  ...require("./service.js"),
-  ...require("./service-container.js")
+  Service,
+  ServiceContainer
 });

+ 1 - 1
package.json

@@ -20,7 +20,7 @@
     "format": "prettier --write \"./src/**/*.js\"",
     "test": "npm run lint && c8 --reporter=text-summary mocha",
     "test:coverage": "npm run lint && c8 --reporter=text mocha",
-    "build:cjs": "rimraf ./dist/cjs && node build-cjs.js",
+    "build:cjs": "rimraf ./dist/cjs && node --no-warnings=ExperimentalWarning build-cjs.js",
     "prepare": "husky"
   },
   "repository": {