Browse Source

refactor: removes type definitions

e22m4u 3 days ago
parent
commit
b5cc2d5eec

+ 0 - 4
.mocharc.cjs

@@ -1,4 +0,0 @@
-module.exports = {
-  extension: ['js'],
-  spec: 'src/**/*.spec.js',
-}

+ 4 - 0
.mocharc.json

@@ -0,0 +1,4 @@
+{
+  "extension": ["js"],
+  "spec": "src/**/*.spec.js"
+}

+ 56 - 328
README.md

@@ -8,7 +8,6 @@
 ## Содержание
 
 - [Установка](#Установка)
-- [Мотивация](#Мотивация)
 - [Описание](#Описание)
 - [Базовые примеры](#Базовые-примеры)
 - [ServiceContainer](#ServiceContainer)
@@ -38,157 +37,6 @@ import {Service} from '@e22m4u/js-service';
 const {Service} = require('@e22m4u/js-service');
 ```
 
-## Мотивация
-
-При росте проекта, построенного на классах, разработчики часто сталкиваются
-с проблемой управления зависимостями. Классы начинают зависеть друг от друга,
-и для их совместной работы требуется где-то создавать экземпляры и передавать
-их в конструкторы или методы других классов. Ручное внедрение зависимостей
-быстро приводит к сложному и запутанному коду.
-
-#### Проблема: Ручное управление зависимостями
-
-Представим типичную ситуацию - есть сервис для работы с пользователями
-`UserService`, который нуждается в логгере `Logger` и клиенте для доступа
-к базе данных `DatabaseClient`.
-
-Без библиотеки это может выглядеть так:
-
-```js
-// зависимости
-class Logger {
-  log(message) {
-    console.log(message);
-  }
-}
-
-class DatabaseClient {
-  query(id) {
-    return {id, name: 'John Doe'};
-  }
-}
-
-// сервис, который зависит от двух других классов
-class UserService {
-  constructor(db, logger) {
-    if (!db || !logger) {
-      throw new Error('Database and Logger are required!');
-    }
-    this.db = db;
-    this.logger = logger;
-  }
-
-  findUser(id) {
-    this.logger.log(`Searching for user with id: ${id}`);
-    return this.db.query(id);
-  }
-}
-
-// -- точка входа в приложение (или где-то в коде) ---
-
-// нужно вручную создать все зависимости
-const logger = new Logger();
-const dbClient = new DatabaseClient();
-
-// нужно вручную передать их в конструктор
-const userService = new UserService(dbClient, logger);
-
-userService.findUser(123);
-```
-
-Недостатки ручного управления зависимостями:
-
-- Жесткая связь и сложность.  
-  Точка входа в приложение превращается в "фабрику", которая знает,
-  как создавать и связывать все компоненты. Если `DatabaseClient` тоже
-  начнет зависеть от `Logger`, порядок создания усложнится.
-
-- Проблемы с тестированием.  
-  Чтобы протестировать `UserService` в изоляции, нужно создать "моки"
-  для `Logger` и `DatabaseClient` и вручную передать их в конструктор.
-  Это громоздко и требует дополнительного кода в каждом тесте.
-
-#### Решение: Инверсия управления
-
-Эта библиотека была создана для решения именно этих проблем. Она реализует
-принцип *инверсии управления (IoC)*, при котором контроль над созданием
-и предоставлением зависимостей передается от компонента к специализированному
-контейнеру.
-
-С библиотекой код становится проще:
-
-```js
-import {Service} from '@e22m4u/js-service';
-
-// зависимости (остаются простыми классами)
-class Logger {
-  log(message) {
-    console.log(message);
-  }
-}
-
-class DatabaseClient {
-  query(id) {
-    return {id, name: 'John Doe'};
-  }
-}
-
-// сервис наследует `Service` для доступа к `getService`
-class UserService extends Service {
-  findUser(id) {
-    // зависимости запрашиваются "по требованию" где они нужны,
-    // контейнер сам позаботится об их создании и кешировании
-    const logger = this.getService(Logger);
-    const db = this.getService(DatabaseClient);
-    
-    logger.log(`Searching for user with id: ${id}`);
-    return db.query(id);
-  }
-}
-
-// -- точка входа в приложение ---
-
-// мы просто создаем экземпляр нужного сервиса
-const userService = new UserService();
-userService.findUser(123);
-```
-
-Преимущества этого подхода:
-
-- Слабая связанность.  
-  `UserService` больше не знает, как создавать `Logger` или `DatabaseClient`.
-  Он просто заявляет о своей потребности в них, вызывая `this.getService()`.
-
-- Простота и чистота кода.  
-  Точка входа в приложение становится тривиальной. Логика сборки зависимостей
-  полностью инкапсулирована внутри контейнера, который неявно управляется
-  базовым классом `Service`
-
-- Легкость тестирования.  
-  Подменить зависимость стало невероятно просто. Метод `setService` позволяет
-  "на лету" подставить мок-объект.
-
-Пример подмены зависимости (mocking):
-
-```js
-// в файле теста
-const userService = new UserService();
-
-// создание мок-логгера
-const mockLogger = {log: () => {}}; // не будет писать в консоль
-
-// подмена реализации Logger в контейнере этого сервиса
-userService.setService(Logger, mockLogger);
-
-// теперь при вызове findUser будет использован наш мок-объект
-userService.findUser(456);
-```
-
-Библиотека избавляет от рутины ручного управления зависимостями, делая
-архитектуру проекта гибкой, масштабируемой и легко тестируемой. Разработчик
-может сосредоточиться на бизнес-логике, а не на том, как и в каком порядке
-создавать и связывать объекты.
-
 ## Описание
 
 Модуль экспортирует два основных класса, `ServiceContainer` и `Service`,
@@ -340,21 +188,12 @@ const myService = container.get(MyService);
 - [`add(ctor, ...args)`](#servicecontaineradd) добавить конструктор в контейнер (ленивая инициализация);
 - [`use(ctor, ...args)`](#servicecontaineruse) добавить конструктор и сразу создать экземпляр;
 - [`set(ctor, service)`](#servicecontainerset) добавить конструктор и связанный с ним готовый экземпляр;
-- [`find(predicate, noParent = false)`](#servicecontainerfind) найти сервис удовлетворяющий условию;
+- [`find(predicate, [noParent])`](#servicecontainerfind) найти сервис удовлетворяющий условию;
 - [`getParent()`](#servicecontainergetparent-и-servicecontainerhasparent) получить родительский сервис-контейнер;
 - [`hasParent()`](#servicecontainergetparent-и-servicecontainerhasparent) проверить наличие родительского сервис-контейнера;
 
 В сигнатурах методов используется вспомогательный тип конструктора:
 
-```ts
-/**
- * Конструктор класса.
- */
-interface Constructor<T extends object = object> {
-  new (...args: any[]): T;
-}
-```
-
 ### serviceContainer.get
 
 Метод `get` класса `ServiceContainer` создает экземпляр
@@ -363,15 +202,10 @@ interface Constructor<T extends object = object> {
 
 Сигнатура:
 
-```ts
-/**
- * Получить существующий или новый экземпляр.
- *
- * @param ctor
- * @param args
- */
-get<T extends object>(ctor: Constructor<T>, ...args: any[]): T;
-```
+- `get(ctor, ...args)`
+  - `ctor: Function`: класс сервиса;
+  - `...args: *[]`: аргументы конструктора;
+  - возвращает новый или существующий экземпляр сервиса;
 
 Пример:
 
@@ -411,16 +245,10 @@ console.log(myDate3); // Sun May 05 2030 03:00:00
 
 Сигнатура:
 
-```ts
-/**
- * Получить существующий или новый экземпляр,
- * только если конструктор зарегистрирован.
- *
- * @param ctor
- * @param args
- */
-getRegistered<T extends object>(ctor: Constructor<T>, ...args: any[]): T;
-```
+- `getRegistered(ctor, ...args)`
+  - `ctor: Function`: класс сервиса;
+  - `...args: *[]`: аргументы конструктора;
+  - возвращает новый или существующий экземпляр сервиса;
 
 Пример:
 
@@ -445,14 +273,9 @@ container.getRegistered(UnregisteredService);
 
 Сигнатура:
 
-```ts
-/**
- * Проверить существование конструктора в контейнере.
- *
- * @param ctor
- */
-has<T extends object>(ctor: Constructor<T>): boolean;
-```
+- `has(ctor)`
+  - `ctor: Function`: класс сервиса;
+  - возвращает `true` если класс зарегистрирован;
 
 Пример:
 
@@ -474,15 +297,10 @@ console.log(container.has(MyService)); // true
 
 Сигнатура:
 
-```ts
-/**
- * Добавить конструктор в контейнер.
- *
- * @param ctor
- * @param args
- */
-add<T extends object>(ctor: Constructor<T>, ...args: any[]): this;
-```
+- `add(ctor, ...args)`
+  - `ctor: Function`: класс сервиса;
+  - `...args: *[]`: аргументы конструктора;
+  - возвращает экземпляр сервис-контейнера;
 
 Пример:
 
@@ -511,15 +329,10 @@ console.log('After get');
 
 Сигнатура:
 
-```ts
-/**
- * Добавить конструктор и создать экземпляр.
- *
- * @param ctor
- * @param args
- */
-use<T extends object>(ctor: Constructor<T>, ...args: any[]): this;
-```
+- `use(ctor, ...args)`
+  - `ctor: Function`: класс сервиса;
+  - `...args: *[]`: аргументы конструктора;
+  - возвращает новый экземпляр сервиса;
 
 Пример:
 
@@ -546,15 +359,10 @@ const service = container.get(MyService); // возвращает готовый
 
 Сигнатура:
 
-```ts
-/**
- * Добавить конструктор и связанный экземпляр.
- *
- * @param ctor
- * @param service
- */
-set<T extends object>(ctor: Constructor<T>, service: T): this;
-```
+- `set(ctor, service)`
+  - `ctor: Function`: класс сервиса;
+  - `service: object`: экземпляр сервиса;
+  - возвращает экземпляр сервис-контейнера;
 
 Пример:
 
@@ -587,26 +395,10 @@ console.log(api === mock); // true
 
 Сигнатура:
 
-```ts
-/**
- * Найти сервис удовлетворяющий условию.
- *
- * @param predicate
- * @param noParent
- */
-find<T extends object>(
-  predicate: FindServicePredicate<T>,
-  noParent?: boolean,
-): T | undefined;
-
-/**
- * Определение функции-предиката.
- */
-type FindServicePredicate<T extends object> = (
-  ctor: Constructor<T>,
-  container: ServiceContainer,
-) => boolean;
-```
+- `find(predicate, [noParent])`
+  - `predicate: Function`: функция-предикат для проверки конструктора;
+  - `noParent?: boolean`: отключить поиск в родительских контейнерах;
+  - возвращает найденный экземпляр или `undefined`;
 
 Пример:
 
@@ -658,20 +450,6 @@ console.log(service2); // undefined
 проверяет наличие родителя, а `getParent` возвращает его или выбрасывает
 ошибку, если родителя нет.
 
-Сигнатура:
-
-```ts
-/**
- * Получить родительский сервис-контейнер или выбросить ошибку.
- */
-getParent(): ServiceContainer;
-
-/**
- * Проверить наличие родительского сервис-контейнера.
- */
-hasParent(): boolean;
-```
-
 Пример:
 
 ```js
@@ -719,7 +497,7 @@ console.log(hasService); // true
 - [`addService(ctor, ...args)`](#serviceaddservice) добавить конструктор в контейнер;
 - [`useService(ctor, ...args)`](#serviceuseservice) добавить конструктор и создать экземпляр;
 - [`setService(ctor, service)`](#servicesetservice) добавить конструктор и его экземпляр;
-- [`findService(predicate, noParent = false)`](#servicefindservice) найти сервис удовлетворяющий условию;
+- [`findService(predicate, [noParent])`](#servicefindservice) найти сервис удовлетворяющий условию;
 
 Сервисом может являться совершенно любой класс. Однако, если это
 наследник класса `Service`, то такой сервис позволяет инкапсулировать
@@ -774,15 +552,10 @@ const app = new App();
 
 Сигнатура:
 
-```ts
-/**
- * Получить существующий или новый экземпляр.
- *
- * @param ctor
- * @param args
- */
-getService<T extends object>(ctor: Constructor<T>, ...args: any[]): T;
-```
+- `getService(ctor, ...args)`
+  - `ctor: Function`: класс сервиса;
+  - `...args: *[]`: аргументы конструктора;
+  - возвращает новый или существующий экземпляр сервиса;
 
 Пример:
 
@@ -804,19 +577,10 @@ console.log(foo3 === foo4);               // true
 
 Сигнатура:
 
-```ts
-/**
- * Получить существующий или новый экземпляр,
- * только если конструктор зарегистрирован.
- *
- * @param ctor
- * @param args
- */
-getRegisteredService<T extends object>(
-  ctor: Constructor<T>,
-  ...args: any[],
-): T;
-```
+- `getRegisteredService(ctor, ...args)`
+  - `ctor: Function`: класс сервиса;
+  - `...args: *[]`: аргументы конструктора;
+  - возвращает новый или существующий экземпляр сервиса;
 
 Пример:
 
@@ -844,14 +608,9 @@ class MyService extends Service {
 
 Сигнатура:
 
-```ts
-/**
- * Проверка существования конструктора в контейнере.
- *
- * @param ctor
- */
-hasService<T extends object>(ctor: Constructor<T>): boolean;
-```
+- `hasService(ctor)`
+  - `ctor: Function`: класс сервиса;
+  - возвращает `true` если класс зарегистрирован;
 
 Пример:
 
@@ -876,15 +635,10 @@ class MyService extends Service {
 
 Сигнатура:
 
-```ts
-/**
- * Добавить конструктор в контейнер.
- *
- * @param ctor
- * @param args
- */
-addService<T extends object>(ctor: Constructor<T>, ...args: any[]): this;
-```
+- `addService(ctor, ...args)`
+  - `ctor: Function`: класс сервиса;
+  - `...args: *[]`: аргументы конструктора;
+  - возвращает экземпляр сервис-контейнера;
 
 Пример:
 
@@ -908,15 +662,10 @@ class App extends Service {
 
 Сигнатура:
 
-```ts
-/**
- * Добавить конструктор и создать экземпляр.
- *
- * @param ctor
- * @param args
- */
-useService<T extends object>(ctor: Constructor<T>, ...args: any[]): this;
-```
+- `useService(ctor, ...args)`
+  - `ctor: Function`: класс сервиса;
+  - `...args: *[]`: аргументы конструктора;
+  - возвращает новый экземпляр сервиса;
 
 Пример:
 
@@ -943,15 +692,10 @@ class App extends Service {
 
 Сигнатура:
 
-```ts
-/**
- * Добавить конструктор и связанный экземпляр.
- *
- * @param ctor
- * @param service
- */
-setService<T extends object>(ctor: Constructor<T>, service: T): this;
-```
+- `setService(ctor, service)`
+  - `ctor: Function`: класс сервиса;
+  - `service: object`: экземпляр сервиса;
+  - возвращает экземпляр сервис-контейнера;
 
 Пример:
 
@@ -980,26 +724,10 @@ class MyComponent extends Service {
 
 Сигнатура:
 
-```ts
-/**
- * Найти сервис удовлетворяющий условию.
- *
- * @param predicate
- * @param noParent
- */
-findService<T extends object>(
-  predicate: FindServicePredicate<T>,
-  noParent?: boolean,
-): T | undefined;
-
-/**
- * Определение функции-предиката.
- */
-type FindServicePredicate<T extends object> = (
-  ctor: Constructor<T>,
-  container: ServiceContainer,
-) => boolean;
-```
+- `findService(predicate, [noParent])`
+  - `predicate: Function`: функция-предикат для проверки конструктора;
+  - `noParent?: boolean`: отключить поиск в родительских контейнерах;
+  - возвращает найденный экземпляр или `undefined`;
 
 Пример:
 

+ 3 - 5
dist/cjs/index.cjs

@@ -44,15 +44,13 @@ var _ServiceContainer = class _ServiceContainer {
   /**
    * Services map.
    *
-   * @type {Map<any, any>}
-   * @private
+   * @type {Map<*, *>}
    */
   _services = /* @__PURE__ */ new Map();
   /**
    * Parent container.
    *
    * @type {ServiceContainer}
-   * @private
    */
   _parent;
   /**
@@ -212,7 +210,7 @@ var _ServiceContainer = class _ServiceContainer {
   /**
    * Найти сервис удовлетворяющий условию.
    *
-   * @param {function(Function, ServiceContainer): boolean} predicate
+   * @param {Function} predicate
    * @param {boolean} noParent
    * @returns {*}
    */
@@ -340,7 +338,7 @@ var _Service = class _Service {
   /**
    * Найти сервис удовлетворяющий условию.
    *
-   * @param {function(Function, ServiceContainer): boolean} predicate
+   * @param {Function} predicate
    * @param {boolean} noParent
    * @returns {*}
    */

+ 5 - 2
eslint.config.js

@@ -2,6 +2,7 @@ import globals from 'globals';
 import eslintJs from '@eslint/js';
 import eslintJsdocPlugin from 'eslint-plugin-jsdoc';
 import eslintMochaPlugin from 'eslint-plugin-mocha';
+import eslintImportPlugin from 'eslint-plugin-import';
 import eslintPrettierConfig from 'eslint-config-prettier';
 import eslintChaiExpectPlugin from 'eslint-plugin-chai-expect';
 
@@ -10,20 +11,22 @@ export default [{
     globals: {
       ...globals.es2021,
       ...globals.mocha,
-      ...globals.node,
     },
   },
   plugins: {
     'jsdoc': eslintJsdocPlugin,
     'mocha': eslintMochaPlugin,
+    'import': eslintImportPlugin,
     'chai-expect': eslintChaiExpectPlugin,
   },
   rules: {
     ...eslintJs.configs.recommended.rules,
     ...eslintPrettierConfig.rules,
-    ...eslintJsdocPlugin.configs['flat/recommended-error'].rules,
+    ...eslintImportPlugin.flatConfigs.recommended.rules,
     ...eslintMochaPlugin.configs.recommended.rules,
     ...eslintChaiExpectPlugin.configs['recommended-flat'].rules,
+    ...eslintJsdocPlugin.configs['flat/recommended-error'].rules,
+    'no-duplicate-imports': 'error',
     'jsdoc/reject-any-type': 0,
     'jsdoc/reject-function-type': 0,
     'jsdoc/require-param-description': 0,

+ 0 - 2
tsconfig.json → jsconfig.json

@@ -1,7 +1,5 @@
 {
   "compilerOptions": {
-    "rootDir": "src",
-    "noEmit": true,
     "target": "es2022",
     "module": "NodeNext",
     "moduleResolution": "NodeNext"

+ 10 - 12
package.json

@@ -11,17 +11,15 @@
     "Locator",
     "Container"
   ],
-  "homepage": "https://github.com/e22m4u/js-service",
+  "homepage": "https://gitrepos.ru/e22m4u/js-service",
   "repository": {
     "type": "git",
-    "url": "git+https://github.com/e22m4u/js-service.git"
+    "url": "git+https://gitrepos.ru/e22m4u/js-service.git"
   },
   "type": "module",
-  "types": "./src/index.d.ts",
   "module": "./src/index.js",
   "main": "./dist/cjs/index.cjs",
   "exports": {
-    "types": "./src/index.d.ts",
     "import": "./src/index.js",
     "require": "./dist/cjs/index.cjs"
   },
@@ -29,17 +27,17 @@
     "node": ">=12"
   },
   "scripts": {
-    "lint": "tsc && eslint ./src",
-    "lint:fix": "tsc && eslint ./src --fix",
+    "lint": "eslint ./src",
+    "lint:fix": "eslint ./src --fix",
     "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 --no-warnings=ExperimentalWarning build-cjs.js",
+    "build:cjs": "rimraf ./dist/cjs && node build-cjs.js",
     "prepare": "husky"
   },
   "dependencies": {
-    "@e22m4u/js-debug": "~0.3.3",
-    "@e22m4u/js-format": "~0.2.1"
+    "@e22m4u/js-debug": "~0.4.0",
+    "@e22m4u/js-format": "~0.3.0"
   },
   "devDependencies": {
     "@commitlint/cli": "~20.1.0",
@@ -52,13 +50,13 @@
     "eslint": "~9.39.1",
     "eslint-config-prettier": "~10.1.8",
     "eslint-plugin-chai-expect": "~3.1.0",
+    "eslint-plugin-import": "^2.32.0",
     "eslint-plugin-jsdoc": "~61.4.1",
     "eslint-plugin-mocha": "~11.2.0",
     "globals": "~16.5.0",
     "husky": "~9.1.7",
     "mocha": "~11.7.5",
-    "prettier": "~3.6.2",
-    "rimraf": "~6.1.2",
-    "typescript": "~5.9.3"
+    "prettier": "~3.7.3",
+    "rimraf": "~6.1.2"
   }
 }

+ 0 - 107
src/debuggable-service.d.ts

@@ -1,107 +0,0 @@
-import {Service} from './service.js';
-import {Constructor} from './types.js';
-import {Debuggable} from '@e22m4u/js-debug';
-import {DebuggableOptions} from '@e22m4u/js-debug';
-import {FindServicePredicate, ServiceContainer} from './service-container.js';
-
-/**
- * Debuggable service.
- */
-export class DebuggableService extends Debuggable implements Service {
-  /**
-   * Kind.
-   */
-  static readonly kinds: string[];
-
-  /**
-   * Container.
-   */
-  container: ServiceContainer;
-
-  /**
-   * Constructor.
-   *
-   * @param container
-   * @param options
-   */
-  constructor(
-    container?: ServiceContainer,
-    options?: DebuggableOptions,
-  );
-
-  /**
-   * Получить существующий или новый экземпляр.
-   *
-   * @param ctor
-   * @param args
-   */
-  getService<T extends object>(
-    ctor: Constructor<T>,
-    ...args: any[],
-  ): T;
-  
-  /**
-   * Получить существующий или новый экземпляр,
-   * только если конструктор зарегистрирован.
-   *
-   * @param ctor
-   * @param args
-   */
-  getRegisteredService<T extends object>(
-    ctor: Constructor<T>,
-    ...args: any[],
-  ): T;
-
-  /**
-   * Проверка существования конструктора в контейнере.
-   *
-   * @param ctor
-   */
-  hasService<T extends object>(
-    ctor: Constructor<T>,
-  ): boolean;
-
-  /**
-   * Добавить конструктор в контейнер.
-   *
-   * @param ctor
-   * @param args
-   */
-  addService<T extends object>(
-    ctor: Constructor<T>,
-    ...args: any[],
-  ): this;
-
-  /**
-   * Добавить конструктор и создать экземпляр.
-   *
-   * @param ctor
-   * @param args
-   */
-  useService<T extends object>(
-    ctor: Constructor<T>,
-    ...args: any[],
-  ): this;
-
-  /**
-   * Добавить конструктор и связанный экземпляр.
-   *
-   * @param ctor
-   * @param service
-   */
-  setService<T extends object>(
-    ctor: Constructor<T>,
-    service: T,
-  ): this;
-
-  /**
-   * Найти сервис удовлетворяющий условию.
-   *
-   * @param predicate
-   * @param noParent
-   */
-  findService<T extends object>(
-    predicate: FindServicePredicate<T>,
-    noParent?: boolean,
-  ): T | undefined;
-}

+ 0 - 1
src/errors/index.d.ts

@@ -1 +0,0 @@
-export * from './invalid-argument-error.js';

+ 0 - 6
src/errors/invalid-argument-error.d.ts

@@ -1,6 +0,0 @@
-import {Errorf} from '@e22m4u/js-format';
-
-/**
- * Invalid argument error.
- */
-export declare class InvalidArgumentError extends Errorf {}

+ 0 - 5
src/index.d.ts

@@ -1,5 +0,0 @@
-export * from './types.js';
-export * from './service.js';
-export * from './service-container.js';
-export * from './debuggable-service.js';
-export * from './utils/is-service-container.js';

+ 0 - 1
src/index.js

@@ -1,4 +1,3 @@
-export * from './types.js';
 export * from './service.js';
 export * from './service-container.js';
 export * from './debuggable-service.js';

+ 0 - 105
src/service-container.d.ts

@@ -1,105 +0,0 @@
-import {Constructor} from './types.js';
-
-/**
- * Find service predicate.
- */
-export type FindServicePredicate<T extends object> = (
-  ctor: Constructor<T>,
-  container: ServiceContainer,
-) => boolean;
-
-/**
- * Service container.
- */
-export declare class ServiceContainer {
-  /**
-   * Constructor.
-   *
-   * @param parent
-   */
-  constructor(parent?: ServiceContainer);
-
-  /**
-   * Получить родительский сервис-контейнер или выбросить ошибку.
-   */
-  getParent(): ServiceContainer;
-
-  /**
-   * Проверить наличие родительского сервис-контейнера.
-   */
-  hasParent(): boolean;
-
-  /**
-   * Получить существующий или новый экземпляр.
-   *
-   * @param ctor
-   * @param args
-   */
-  get<T extends object>(
-    ctor: Constructor<T>,
-    ...args: any[],
-  ): T;
-
-  /**
-   * Получить существующий или новый экземпляр,
-   * только если конструктор зарегистрирован.
-   *
-   * @param ctor
-   * @param args
-   */
-  getRegistered<T extends object>(
-    ctor: Constructor<T>,
-    ...args: any[],
-  ): T;
-
-  /**
-   * Проверить существование конструктора в контейнере.
-   *
-   * @param ctor
-   */
-  has<T extends object>(ctor: Constructor<T>): boolean;
-
-  /**
-   * Добавить конструктор в контейнер.
-   *
-   * @param ctor
-   * @param args
-   */
-  add<T extends object>(
-    ctor: Constructor<T>,
-    ...args: any[],
-  ): this;
-
-  /**
-   * Добавить конструктор и создать экземпляр.
-   *
-   * @param ctor
-   * @param args
-   */
-  use<T extends object>(
-    ctor: Constructor<T>,
-    ...args: any[],
-  ): this;
-
-  /**
-   * Добавить конструктор и связанный экземпляр.
-   *
-   * @param ctor
-   * @param service
-   */
-  set<T extends object>(
-    ctor: Constructor<T>,
-    service: T,
-  ): this;
-
-  /**
-   * Найти сервис удовлетворяющий условию.
-   *
-   * @param predicate
-   * @param noParent
-   */
-  find<T extends object>(
-    predicate: FindServicePredicate<T>,
-    noParent?: boolean,
-  ): T | undefined;
-}

+ 2 - 4
src/service-container.js

@@ -22,8 +22,7 @@ export class ServiceContainer {
   /**
    * Services map.
    *
-   * @type {Map<any, any>}
-   * @private
+   * @type {Map<*, *>}
    */
   _services = new Map();
 
@@ -31,7 +30,6 @@ export class ServiceContainer {
    * Parent container.
    *
    * @type {ServiceContainer}
-   * @private
    */
   _parent;
 
@@ -242,7 +240,7 @@ export class ServiceContainer {
   /**
    * Найти сервис удовлетворяющий условию.
    *
-   * @param {function(Function, ServiceContainer): boolean} predicate
+   * @param {Function} predicate
    * @param {boolean} noParent
    * @returns {*}
    */

+ 5 - 2
src/service-container.spec.js

@@ -2,8 +2,11 @@ import {expect} from 'chai';
 import {Service} from './service.js';
 import {format} from '@e22m4u/js-format';
 import {createSpy} from '@e22m4u/js-spy';
-import {ServiceContainer} from './service-container.js';
-import {SERVICE_CONTAINER_CLASS_NAME} from './service-container.js';
+
+import {
+  ServiceContainer,
+  SERVICE_CONTAINER_CLASS_NAME,
+} from './service-container.js';
 
 describe('ServiceContainer', function () {
   it('should expose static property "kinds"', function () {

+ 0 - 105
src/service.d.ts

@@ -1,105 +0,0 @@
-import {Constructor} from './types.js';
-import {FindServicePredicate, ServiceContainer} from './service-container.js';
-
-/**
- * Service class name.
- */
-export const SERVICE_CLASS_NAME: 'Service';
-
-/**
- * Service.
- */
-export declare class Service {
-  /**
-   * Kind.
-   */
-  static readonly kinds: string[];
-
-  /**
-   * Container.
-   */
-  container: ServiceContainer;
-
-  /**
-   * Constructor.
-   *
-   * @param container
-   */
-  constructor(container?: ServiceContainer);
-
-  /**
-   * Получить существующий или новый экземпляр.
-   *
-   * @param ctor
-   * @param args
-   */
-  getService<T extends object>(
-    ctor: Constructor<T>,
-    ...args: any[],
-  ): T;
-
-  /**
-   * Получить существующий или новый экземпляр,
-   * только если конструктор зарегистрирован.
-   *
-   * @param ctor
-   * @param args
-   */
-  getRegisteredService<T extends object>(
-    ctor: Constructor<T>,
-    ...args: any[],
-  ): T;
-
-  /**
-   * Проверка существования конструктора в контейнере.
-   *
-   * @param ctor
-   */
-  hasService<T extends object>(
-    ctor: Constructor<T>,
-  ): boolean;
-
-  /**
-   * Добавить конструктор в контейнер.
-   *
-   * @param ctor
-   * @param args
-   */
-  addService<T extends object>(
-    ctor: Constructor<T>,
-    ...args: any[],
-  ): this;
-
-  /**
-   * Добавить конструктор и создать экземпляр.
-   *
-   * @param ctor
-   * @param args
-   */
-  useService<T extends object>(
-    ctor: Constructor<T>,
-    ...args: any[],
-  ): this;
-
-  /**
-   * Добавить конструктор и связанный экземпляр.
-   *
-   * @param ctor
-   * @param service
-   */
-  setService<T extends object>(
-    ctor: Constructor<T>,
-    service: T,
-  ): this;
-
-  /**
-   * Найти сервис удовлетворяющий условию.
-   *
-   * @param predicate
-   * @param noParent
-   */
-  findService<T extends object>(
-    predicate: FindServicePredicate<T>,
-    noParent?: boolean,
-  ): T | undefined;
-}

+ 1 - 1
src/service.js

@@ -109,7 +109,7 @@ export class Service {
   /**
    * Найти сервис удовлетворяющий условию.
    *
-   * @param {function(Function, ServiceContainer): boolean} predicate
+   * @param {Function} predicate
    * @param {boolean} noParent
    * @returns {*}
    */

+ 6 - 4
src/service.spec.js

@@ -1,8 +1,10 @@
 import {expect} from 'chai';
-import {Service} from './service.js';
-import {SERVICE_CLASS_NAME} from './service.js';
-import {ServiceContainer} from './service-container.js';
-import {SERVICE_CONTAINER_CLASS_NAME} from './service-container.js';
+import {Service, SERVICE_CLASS_NAME} from './service.js';
+
+import {
+  ServiceContainer,
+  SERVICE_CONTAINER_CLASS_NAME,
+} from './service-container.js';
 
 describe('Service', function () {
   it('should expose static property "kinds"', function () {

+ 0 - 7
src/types.d.ts

@@ -1,7 +0,0 @@
-/**
- * A callable type with "new" operator allows
- * class and constructor.
- */
-export interface Constructor<T extends object = object> {
-  new (...args: any[]): T;
-}

+ 0 - 1
src/types.js

@@ -1 +0,0 @@
-export {};

+ 0 - 1
src/utils/index.d.ts

@@ -1 +0,0 @@
-export * from './is-service-container.js';

+ 0 - 10
src/utils/is-service-container.d.ts

@@ -1,10 +0,0 @@
-import {ServiceContainer} from '../service-container.js';
-
-/**
- * Определяет, является ли аргумент сервис-контейнером.
- *
- * @param container
- */
-export declare function isServiceContainer(
-  container: unknown,
-): container is ServiceContainer;

+ 4 - 4
src/utils/is-service-container.js

@@ -10,9 +10,9 @@ import {SERVICE_CONTAINER_CLASS_NAME} from '../service-container.js';
 export function isServiceContainer(container) {
   return Boolean(
     container &&
-      typeof container === 'object' &&
-      typeof container.constructor === 'function' &&
-      Array.isArray(container.constructor.kinds) &&
-      container.constructor.kinds.includes(SERVICE_CONTAINER_CLASS_NAME),
+    typeof container === 'object' &&
+    typeof container.constructor === 'function' &&
+    Array.isArray(container.constructor.kinds) &&
+    container.constructor.kinds.includes(SERVICE_CONTAINER_CLASS_NAME),
   );
 }

+ 5 - 2
src/utils/is-service-container.spec.js

@@ -1,7 +1,10 @@
 import {expect} from 'chai';
-import {ServiceContainer} from '../service-container.js';
 import {isServiceContainer} from './is-service-container.js';
-import {SERVICE_CONTAINER_CLASS_NAME} from '../service-container.js';
+
+import {
+  ServiceContainer,
+  SERVICE_CONTAINER_CLASS_NAME,
+} from '../service-container.js';
 
 describe('isServiceContainer', function () {
   it('should return true for ServiceContainer instance', function () {