@biorate/connector 3.1.0 → 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +181 -21
  2. package/package.json +5 -5
package/README.md CHANGED
@@ -1,49 +1,209 @@
1
- # Connector
1
+ # @biorate/connector
2
2
 
3
- Connector interface
3
+ Abstract base class for creating typed, config‑driven connection managers backed by `@biorate/inversion` and `@biorate/config`.
4
4
 
5
- ### Examples:
5
+ ## Features
6
6
 
7
- ```ts
8
- import { Connector, IConnector } from '../..';
9
- import { inject, container, Types, Core } from '@biorate/inversion';
10
- import { IConfig, Config } from '@biorate/config';
7
+ - **Abstract `Connector<C, R>`** — define `connect(config): Promise<R>` for any resource.
8
+ - **Config‑driven** reads an array of connection configs from `this.namespace` in `@biorate/config`.
9
+ - **Auto‑connect** on `@init()`, creates all connections defined in config.
10
+ - **Named connections** access by name via `.connection(name)` or `.get(name)`.
11
+ - **Current connection** — first config entry becomes the default; switch via `.use(name)`.
12
+ - **Error handling** — typed errors for missing or empty connections.
11
13
 
12
- export class Connection {
13
- public name: string;
14
+ ## Installation
14
15
 
15
- public constructor(name: string) {
16
- this.name = name;
17
- }
16
+ ```bash
17
+ pnpm add @biorate/connector
18
+ ```
19
+
20
+ Requires `@biorate/config`, `@biorate/errors`, `@biorate/inversion`.
21
+
22
+ ## Quick start
23
+
24
+ ```ts
25
+ import { Connector } from '@biorate/connector';
26
+
27
+ class Connection {
28
+ constructor(public name: string) {}
18
29
  }
19
30
 
20
- export class TestConnector extends Connector<{ name: string }, Connection> {
21
- protected namespace = 'TestConnector';
31
+ class MyConnector extends Connector<{ name: string }, Connection> {
32
+ protected namespace = 'MyConnector';
22
33
 
23
- protected async connect(config) {
34
+ protected async connect(config: { name: string }) {
24
35
  return new Connection(config.name);
25
36
  }
26
37
  }
38
+ ```
39
+
40
+ With DI:
41
+
42
+ ```ts
43
+ import { Core, container, Types } from '@biorate/inversion';
44
+ import { IConfig, Config } from '@biorate/config';
27
45
 
28
- export class Root extends Core() {
29
- @inject(TestConnector) public connector: IConnector<{ name: string }, Connection>;
46
+ class Root extends Core() {
47
+ @inject(MyConnector) public connector: MyConnector;
30
48
  }
31
49
 
32
50
  container.bind(Types.Config).to(Config).inSingletonScope();
33
- container.bind(TestConnector).toSelf().inSingletonScope();
51
+ container.bind(MyConnector).toSelf().inSingletonScope();
34
52
  container.bind(Root).toSelf().inSingletonScope();
35
53
 
36
54
  container.get<IConfig>(Types.Config).merge({
37
- TestConnector: [{ name: 'test-connection' }],
55
+ MyConnector: [{ name: 'db-1' }, { name: 'db-2' }],
38
56
  });
39
57
 
40
58
  (async () => {
41
59
  const root = container.get<Root>(Root);
42
60
  await root.$run();
43
- console.log(root.connector.connection('test-connection')); // Connection { name: 'test-connection' }
61
+
62
+ console.log(root.connector.connection('db-1')); // Connection { name: 'db-1' }
63
+ console.log(root.connector.current); // Connection { name: 'db-1' }
64
+
65
+ root.connector.use('db-2');
66
+ console.log(root.connector.current); // Connection { name: 'db-2' }
44
67
  })();
45
68
  ```
46
69
 
70
+ ## API Reference
71
+
72
+ ### `Connector<C, R>` abstract class
73
+
74
+ | Member | Type | Description |
75
+ |---------------------------|-------------------------------|------------------------------------------------|
76
+ | `namespace` (abstract) | `string` | Config key — array of `C` objects. |
77
+ | `connect(config)` (abstract) | `(config: C) => Promise<R>` | Create a single connection. |
78
+ | `current` | `R \| undefined` | Currently selected connection. |
79
+ | `connections` | `Map<string, R>` | All created connections (name → instance). |
80
+ | `create(config)` | `(config: C) => Promise<R>` | Create connection if not already cached. |
81
+ | `connection(name?)` | `(name?: string) => R` | Get connection by name (or current). |
82
+ | `get(name?)` | `(name?: string) => R` | Alias for `connection()`. |
83
+ | `use(name)` | `(name: string) => void` | Switch current connection. |
84
+ | `initialize()` | `@init()` | Reads config array, creates all connections. |
85
+
86
+ ### Config interface
87
+
88
+ ```ts
89
+ interface IConnectorConfig {
90
+ name: string; // connection identifier (unique per connector)
91
+ // … plus any additional fields for your resource
92
+ }
93
+ ```
94
+
95
+ ### Errors
96
+
97
+ | Error | Condition |
98
+ |------------------------------------|--------------------------------------------------|
99
+ | `ConnectorConnectionNotExistsError`| Calling `connection(name)` / `use(name)` with unknown name. |
100
+ | `ConnectorEmptyConnectionsError` | Calling `connection()` when no connections exist. |
101
+
102
+ ## Usage patterns
103
+
104
+ ### Single connection
105
+
106
+ ```ts
107
+ class MyConnector extends Connector<{ name: string; host: string; port: number }, Client> {
108
+ protected namespace = 'MyConnector';
109
+
110
+ protected async connect(config: { name: string; host: string; port: number }) {
111
+ const client = new Client();
112
+ await client.connect(config.host, config.port);
113
+ return client;
114
+ }
115
+ }
116
+ ```
117
+
118
+ Config:
119
+
120
+ ```json
121
+ {
122
+ "MyConnector": [{ "name": "default", "host": "localhost", "port": 5432 }]
123
+ }
124
+ ```
125
+
126
+ ### Multi‑connection (read replicas)
127
+
128
+ ```ts
129
+ {
130
+ "MyConnector": [
131
+ { "name": "primary", "host": "db-1.internal", "port": 5432 },
132
+ { "name": "replica-1", "host": "db-2.internal", "port": 5432 },
133
+ { "name": "replica-2", "host": "db-3.internal", "port": 5432 },
134
+ ]
135
+ }
136
+ ```
137
+
138
+ ```ts
139
+ // Switch for read operations:
140
+ connector.use('replica-1');
141
+ const data = await connector.current.query('SELECT …');
142
+
143
+ // Switch back for writes:
144
+ connector.use('primary');
145
+ ```
146
+
147
+ ### Dynamic connection creation
148
+
149
+ ```ts
150
+ class MyConnector extends Connector<{ name: string; url: string }, Resource> {
151
+ protected namespace = 'MyConnector';
152
+ protected async connect(config: { name: string; url: string }) {
153
+ return new Resource(config.url);
154
+ }
155
+ }
156
+
157
+ // At runtime:
158
+ await connector.create({ name: 'ad-hoc', url: 'https://…' });
159
+ const resource = connector.connection('ad-hoc');
160
+ ```
161
+
162
+ ### Type override for config
163
+
164
+ ```ts
165
+ interface RedisConfig extends IConnectorConfig {
166
+ host: string;
167
+ port: number;
168
+ db: number;
169
+ }
170
+
171
+ class RedisConnector extends Connector<RedisConfig, RedisClient> {
172
+ protected namespace = 'RedisConnector';
173
+ protected async connect(config: RedisConfig) {
174
+ return new RedisClient({ host: config.host, port: config.port, db: config.db });
175
+ }
176
+ }
177
+ ```
178
+
179
+ ## Architecture
180
+
181
+ ```
182
+ ┌─────────────────────────────────────────────┐
183
+ │ Connector │ abstract class
184
+ ├─────────────────────────────────────────────┤
185
+ │ namespace: string ─── config key │
186
+ │ #connections: Map<name, R> │
187
+ │ #current: R ─── selected │
188
+ │ │
189
+ │ @init() initialize() │
190
+ │ ├── for each config in namespace[] │
191
+ │ │ └── this.create(config) │
192
+ │ │ └── this.connect(config) ← abstract
193
+ │ └── set #current = first entry │
194
+ │ │
195
+ │ connection(name?) → R │
196
+ │ use(name) → void │
197
+ │ create(config) → Promise<R> │
198
+ └─────────────────────────────────────────────┘
199
+ ▲ extends
200
+
201
+ ┌─────────────────────────────────────────────┐
202
+ │ RedisConnector / MongoConnector … │
203
+ │ connect(config) → Promise<R> │
204
+ └─────────────────────────────────────────────┘
205
+ ```
206
+
47
207
  ### Learn
48
208
 
49
209
  - Documentation can be found here - [docs](https://biorate.github.io/core/modules/connector.html).
@@ -52,7 +212,7 @@ container.get<IConfig>(Types.Config).merge({
52
212
 
53
213
  See the [CHANGELOG](https://github.com/biorate/core/blob/master/packages/%40biorate/connector/CHANGELOG.md)
54
214
 
55
- ### License
215
+ ## License
56
216
 
57
217
  [MIT](https://github.com/biorate/core/blob/master/packages/%40biorate/connector/LICENSE)
58
218
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@biorate/connector",
3
- "version": "3.1.0",
3
+ "version": "3.1.1",
4
4
  "description": "Connector interface",
5
5
  "main": "./dist/cjs/index.js",
6
6
  "module": "./dist/esm/index.js",
@@ -45,10 +45,10 @@
45
45
  "keywords": [],
46
46
  "author": "llevkin",
47
47
  "license": "MIT",
48
- "gitHead": "010221e54e07d16098c47b67bc7ed38ab0e43fb2",
48
+ "gitHead": "ff1dcf14a733ce8004ca582d2c421a2154ce97cb",
49
49
  "dependencies": {
50
- "@biorate/config": "3.2.0",
51
- "@biorate/errors": "3.1.0",
52
- "@biorate/inversion": "3.1.0"
50
+ "@biorate/config": "3.2.1",
51
+ "@biorate/errors": "3.1.1",
52
+ "@biorate/inversion": "3.1.1"
53
53
  }
54
54
  }