@venizia/ignis-docs 0.2.0 → 0.2.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.
- package/README.md +14 -14
- package/content/best-practices/api-usage-examples.md +39 -19
- package/content/best-practices/architectural-patterns.md +24 -13
- package/content/best-practices/architecture-decisions.md +29 -16
- package/content/best-practices/code-style-standards/advanced-patterns.md +43 -31
- package/content/best-practices/code-style-standards/constants-configuration.md +19 -4
- package/content/best-practices/code-style-standards/control-flow.md +33 -1
- package/content/best-practices/code-style-standards/documentation.md +28 -8
- package/content/best-practices/code-style-standards/function-patterns.md +15 -4
- package/content/best-practices/code-style-standards/index.md +7 -2
- package/content/best-practices/code-style-standards/naming-conventions.md +27 -3
- package/content/best-practices/code-style-standards/route-definitions.md +9 -5
- package/content/best-practices/code-style-standards/tooling.md +14 -1
- package/content/best-practices/code-style-standards/type-safety.md +39 -6
- package/content/best-practices/common-pitfalls.md +59 -35
- package/content/best-practices/contribution-workflow.md +8 -4
- package/content/best-practices/data-modeling.md +78 -62
- package/content/best-practices/deployment-strategies.md +56 -19
- package/content/best-practices/error-handling.md +247 -153
- package/content/best-practices/index.md +6 -0
- package/content/best-practices/performance-optimization.md +26 -13
- package/content/best-practices/security-guidelines.md +35 -9
- package/content/best-practices/testing-strategies.md +7 -2
- package/content/best-practices/troubleshooting-tips.md +27 -17
- package/content/extensions/components/api-reference.md +109 -323
- package/content/extensions/components/authentication/api.md +489 -602
- package/content/extensions/components/authentication/errors.md +135 -498
- package/content/extensions/components/authentication/index.md +89 -801
- package/content/extensions/components/authentication/usage.md +231 -955
- package/content/extensions/components/authorization/api.md +991 -644
- package/content/extensions/components/authorization/errors.md +204 -208
- package/content/extensions/components/authorization/getting-started.md +227 -0
- package/content/extensions/components/authorization/index.md +88 -795
- package/content/extensions/components/authorization/usage.md +219 -528
- package/content/extensions/components/health-check.md +77 -243
- package/content/extensions/components/index.md +24 -90
- package/content/extensions/components/mail/api.md +553 -285
- package/content/extensions/components/mail/errors.md +76 -62
- package/content/extensions/components/mail/index.md +111 -463
- package/content/extensions/components/mail/usage.md +139 -173
- package/content/extensions/components/request-tracker.md +70 -173
- package/content/extensions/components/socket-io/api.md +462 -785
- package/content/extensions/components/socket-io/errors.md +49 -51
- package/content/extensions/components/socket-io/index.md +69 -372
- package/content/extensions/components/socket-io/usage.md +212 -105
- package/content/extensions/components/static-asset/api.md +461 -141
- package/content/extensions/components/static-asset/errors.md +121 -53
- package/content/extensions/components/static-asset/index.md +84 -606
- package/content/extensions/components/static-asset/usage.md +184 -299
- package/content/extensions/components/template/index.md +3 -3
- package/content/extensions/components/websocket/api.md +311 -404
- package/content/extensions/components/websocket/errors.md +47 -56
- package/content/extensions/components/websocket/index.md +75 -407
- package/content/extensions/components/websocket/usage.md +120 -338
- package/content/extensions/helpers/cron/index.md +52 -160
- package/content/extensions/helpers/crypto/index.md +67 -480
- package/content/extensions/helpers/crypto/reference.md +528 -0
- package/content/extensions/helpers/env/index.md +64 -178
- package/content/extensions/helpers/error/index.md +286 -196
- package/content/extensions/helpers/index.md +61 -47
- package/content/extensions/helpers/inversion/index.md +76 -550
- package/content/extensions/helpers/inversion/reference.md +530 -0
- package/content/extensions/helpers/kafka/admin.md +23 -3
- package/content/extensions/helpers/kafka/compile-binary.md +83 -52
- package/content/extensions/helpers/kafka/consumer.md +65 -28
- package/content/extensions/helpers/kafka/examples.md +46 -253
- package/content/extensions/helpers/kafka/index.md +55 -617
- package/content/extensions/helpers/kafka/producer.md +156 -22
- package/content/extensions/helpers/kafka/schema-registry.md +59 -79
- package/content/extensions/helpers/logger/hf-logger.md +220 -0
- package/content/extensions/helpers/logger/index.md +78 -552
- package/content/extensions/helpers/logger/pino.md +105 -0
- package/content/extensions/helpers/logger/reference.md +937 -0
- package/content/extensions/helpers/network/api.md +276 -195
- package/content/extensions/helpers/network/index.md +87 -524
- package/content/extensions/helpers/queue/index.md +80 -897
- package/content/extensions/helpers/queue/reference.md +494 -0
- package/content/extensions/helpers/redis/index.md +86 -640
- package/content/extensions/helpers/redis/reference.md +784 -0
- package/content/extensions/helpers/secrets/index.md +136 -0
- package/content/extensions/helpers/socket-io/api.md +325 -204
- package/content/extensions/helpers/socket-io/index.md +79 -429
- package/content/extensions/helpers/storage/api.md +584 -464
- package/content/extensions/helpers/storage/index.md +80 -573
- package/content/extensions/helpers/types/index.md +75 -495
- package/content/extensions/helpers/types/reference.md +689 -0
- package/content/extensions/helpers/uid/index.md +176 -189
- package/content/extensions/helpers/websocket/api.md +366 -214
- package/content/extensions/helpers/websocket/index.md +68 -503
- package/content/extensions/helpers/worker-thread/index.md +62 -396
- package/content/extensions/helpers/worker-thread/reference.md +428 -0
- package/content/extensions/index.md +38 -39
- package/content/extensions/src-details/mcp-server.md +96 -548
- package/content/guides/core-concepts/persistent/datasources.md +2 -2
- package/content/guides/core-concepts/persistent/index.md +5 -1
- package/content/guides/core-concepts/persistent/models.md +1 -1
- package/content/guides/core-concepts/persistent/pglite.md +218 -0
- package/content/guides/core-concepts/persistent/postgres-drivers.md +21 -15
- package/content/guides/core-concepts/persistent/search-meilisearch.md +22 -12
- package/content/guides/core-concepts/persistent/search-typesense.md +28 -16
- package/content/guides/core-concepts/persistent/sqlite.md +296 -0
- package/content/guides/core-concepts/persistent/transactions.md +12 -11
- package/content/guides/core-concepts/secrets-vault.md +177 -0
- package/content/guides/core-concepts/services.md +1 -1
- package/content/guides/get-started/5-minute-quickstart.md +59 -206
- package/content/guides/get-started/philosophy.md +135 -670
- package/content/guides/get-started/setup.md +53 -74
- package/content/guides/migrations/redis-helpers-migration.md +5 -4
- package/content/guides/migrations/scoped-rbac-migration.md +5 -5
- package/content/guides/migrations/unified-connectors-migration.md +8 -7
- package/content/guides/tutorials/ecommerce-api.md +3 -8
- package/content/guides/tutorials/realtime-chat.md +1 -1
- package/content/references/base/application.md +64 -22
- package/content/references/base/components.md +3 -3
- package/content/references/base/connectors.md +79 -136
- package/content/references/base/controllers.md +12 -12
- package/content/references/base/datasources-reference.md +600 -0
- package/content/references/base/datasources.md +84 -444
- package/content/references/base/dependency-injection.md +25 -46
- package/content/references/base/filter-system/application-usage.md +95 -123
- package/content/references/base/filter-system/array-operators.md +33 -43
- package/content/references/base/filter-system/comparison-operators.md +55 -63
- package/content/references/base/filter-system/default-filter.md +144 -350
- package/content/references/base/filter-system/fields-order-pagination.md +116 -148
- package/content/references/base/filter-system/index.md +114 -253
- package/content/references/base/filter-system/json-filtering.md +52 -181
- package/content/references/base/filter-system/list-operators.md +28 -44
- package/content/references/base/filter-system/logical-operators.md +69 -114
- package/content/references/base/filter-system/null-operators.md +41 -98
- package/content/references/base/filter-system/pattern-matching.md +48 -51
- package/content/references/base/filter-system/quick-reference.md +93 -196
- package/content/references/base/filter-system/range-operators.md +22 -38
- package/content/references/base/filter-system/tips.md +70 -133
- package/content/references/base/filter-system/use-cases.md +173 -232
- package/content/references/base/grpc-controllers.md +53 -17
- package/content/references/base/index.md +5 -3
- package/content/references/base/middlewares.md +43 -28
- package/content/references/base/models-reference.md +886 -0
- package/content/references/base/models.md +81 -1452
- package/content/references/base/providers.md +8 -8
- package/content/references/base/repositories/advanced.md +281 -419
- package/content/references/base/repositories/index.md +84 -644
- package/content/references/base/repositories/mixins.md +25 -21
- package/content/references/base/repositories/relations.md +194 -375
- package/content/references/base/repositories/soft-deletable.md +67 -55
- package/content/references/base/secrets.md +267 -0
- package/content/references/base/services.md +8 -6
- package/content/references/configuration/environment-variables.md +73 -21
- package/content/references/configuration/index.md +51 -31
- package/content/references/index.md +1 -1
- package/content/references/quick-reference.md +3 -16
- package/content/references/utilities/crypto.md +35 -76
- package/content/references/utilities/date.md +33 -73
- package/content/references/utilities/duration.md +85 -0
- package/content/references/utilities/index.md +6 -2
- package/content/references/utilities/jsx-reference.md +298 -0
- package/content/references/utilities/jsx.md +82 -525
- package/content/references/utilities/module.md +81 -61
- package/content/references/utilities/parse.md +34 -64
- package/content/references/utilities/performance.md +33 -58
- package/content/references/utilities/promise.md +28 -62
- package/content/references/utilities/request.md +58 -218
- package/content/references/utilities/retry.md +139 -0
- package/content/references/utilities/schema.md +43 -137
- package/content/references/utilities/statuses-reference.md +361 -0
- package/content/references/utilities/statuses.md +63 -667
- package/dist/mcp-server/index.js +0 -0
- package/dist/mcp-server/tools/github/list-project-files.tool.d.ts +1 -1
- package/dist/mcp-server/tools/github/list-project-files.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/github/list-project-files.tool.js +3 -3
- package/dist/mcp-server/tools/github/search-code.tool.js +1 -1
- package/dist/mcp-server/tools/github/verify-dependencies.tool.js +1 -1
- package/dist/mcp-server/tools/github/view-source-file.tool.js +1 -1
- package/package.json +24 -23
|
@@ -1,626 +1,189 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
| Class | Extends | Protocol | Type |
|
|
8
|
-
|-------|---------|----------|------|
|
|
9
|
-
| `AxiosNetworkRequest` | `BaseNetworkRequest<'axios'>` | HTTP/HTTPS | Client |
|
|
10
|
-
| `NodeFetchNetworkRequest` | `BaseNetworkRequest<'node-fetch'>` | HTTP/HTTPS | Client |
|
|
11
|
-
| `NetworkTcpClient` | `BaseNetworkTcpClient` | TCP | Client |
|
|
12
|
-
| `NetworkTcpServer` | `BaseNetworkTcpServer` | TCP | Server |
|
|
13
|
-
| `NetworkTlsTcpClient` | `BaseNetworkTcpClient` | TLS/SSL | Client |
|
|
14
|
-
| `NetworkTlsTcpServer` | `BaseNetworkTcpServer` | TLS/SSL | Server |
|
|
15
|
-
| `NetworkUdpClient` | `BaseHelper` | UDP | Client |
|
|
16
|
-
|
|
17
|
-
#### Import Paths
|
|
18
|
-
|
|
19
|
-
```typescript
|
|
20
|
-
// Main package -- TCP, UDP, and Node Fetch
|
|
21
|
-
import {
|
|
22
|
-
NodeFetchNetworkRequest,
|
|
23
|
-
BaseNetworkRequest,
|
|
24
|
-
NetworkTcpClient,
|
|
25
|
-
NetworkTcpServer,
|
|
26
|
-
NetworkTlsTcpClient,
|
|
27
|
-
NetworkTlsTcpServer,
|
|
28
|
-
BaseNetworkTcpClient,
|
|
29
|
-
BaseNetworkTcpServer,
|
|
30
|
-
NetworkUdpClient,
|
|
31
|
-
} from '@venizia/ignis-helpers';
|
|
32
|
-
|
|
33
|
-
// Axios (separate export -- optional peer dependency)
|
|
34
|
-
import {
|
|
35
|
-
AxiosNetworkRequest,
|
|
36
|
-
AxiosFetcher,
|
|
37
|
-
type IAxiosNetworkRequestOptions,
|
|
38
|
-
type IAxiosRequestOptions,
|
|
39
|
-
} from '@venizia/ignis-helpers/axios';
|
|
40
|
-
|
|
41
|
-
// Types
|
|
42
|
-
import type {
|
|
43
|
-
INodeFetchNetworkRequestOptions,
|
|
44
|
-
INodeFetchRequestOptions,
|
|
45
|
-
INetworkTcpClientProps,
|
|
46
|
-
ITcpSocketServerOptions,
|
|
47
|
-
ITcpSocketClient,
|
|
48
|
-
IRequestOptions,
|
|
49
|
-
IFetchable,
|
|
50
|
-
TFetcherVariant,
|
|
51
|
-
} from '@venizia/ignis-helpers';
|
|
52
|
-
```
|
|
1
|
+
---
|
|
2
|
+
title: Network
|
|
3
|
+
description: HTTP request clients, TCP/TLS socket clients and servers, and a UDP client, all built on scoped logging with automatic secret redaction
|
|
4
|
+
difficulty: intermediate
|
|
5
|
+
---
|
|
53
6
|
|
|
54
|
-
|
|
7
|
+
# Network
|
|
55
8
|
|
|
56
|
-
|
|
9
|
+
Network helpers give you HTTP request clients (fetch or Axios), symmetric TCP/TLS socket client-server pairs, and a UDP client. All three share the same options-object construction and scoped logging as the rest of the framework.
|
|
57
10
|
|
|
58
|
-
|
|
11
|
+
## In one example
|
|
59
12
|
|
|
60
|
-
|
|
13
|
+
Extend `NodeFetchNetworkRequest` to build a typed HTTP client backed by native `fetch` - no extra dependency required.
|
|
61
14
|
|
|
62
15
|
```typescript
|
|
63
|
-
import {
|
|
16
|
+
import { NodeFetchNetworkRequest } from '@venizia/ignis-helpers';
|
|
64
17
|
|
|
65
|
-
class
|
|
18
|
+
class GitHubApi extends NodeFetchNetworkRequest {
|
|
66
19
|
constructor() {
|
|
67
20
|
super({
|
|
68
|
-
name: '
|
|
69
|
-
networkOptions: {
|
|
70
|
-
baseUrl: 'https://api.payments.com',
|
|
71
|
-
timeout: 30000,
|
|
72
|
-
headers: {
|
|
73
|
-
'X-API-Key': process.env.PAYMENT_API_KEY,
|
|
74
|
-
},
|
|
75
|
-
},
|
|
21
|
+
name: 'GitHubApi',
|
|
22
|
+
networkOptions: { baseUrl: 'https://api.github.com' },
|
|
76
23
|
});
|
|
77
24
|
}
|
|
78
|
-
}
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
#### `IAxiosNetworkRequestOptions`
|
|
82
|
-
|
|
83
|
-
| Option | Type | Default | Description |
|
|
84
|
-
|--------|------|---------|-------------|
|
|
85
|
-
| `name` | `string` | -- | Helper name, used for scoped logging |
|
|
86
|
-
| `networkOptions.baseUrl` | `string` | `undefined` | Base URL prepended to all request paths |
|
|
87
|
-
| `networkOptions.timeout` | `number` | `60000` | Request timeout in milliseconds |
|
|
88
|
-
| `networkOptions.headers` | `object` | `{ 'content-type': 'application/json; charset=utf-8' }` | Default headers; your values override the default content-type |
|
|
89
|
-
| `networkOptions.*` | `AxiosRequestConfig` | -- | All other Axios config options are accepted |
|
|
90
|
-
|
|
91
|
-
> [!TIP]
|
|
92
|
-
> `AxiosNetworkRequest` sets sensible defaults: `Content-Type: application/json`, `withCredentials: true`, `validateStatus: status < 500`, and `timeout: 60000` (1 minute). Your options override these defaults.
|
|
93
|
-
|
|
94
|
-
#### Node.js Fetch
|
|
95
25
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
constructor() {
|
|
101
|
-
super({
|
|
102
|
-
name: 'MyApiClient',
|
|
103
|
-
networkOptions: {
|
|
104
|
-
baseUrl: 'https://api.example.com',
|
|
105
|
-
headers: {
|
|
106
|
-
'Authorization': 'Bearer my-token',
|
|
107
|
-
},
|
|
108
|
-
credentials: 'include',
|
|
109
|
-
mode: 'cors',
|
|
110
|
-
},
|
|
111
|
-
});
|
|
26
|
+
async getUser(username: string) {
|
|
27
|
+
const url = this.getRequestUrl({ paths: ['users', username] });
|
|
28
|
+
const response = await this.getNetworkService().get({ url });
|
|
29
|
+
return response.json();
|
|
112
30
|
}
|
|
113
31
|
}
|
|
114
32
|
```
|
|
115
33
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
| Option | Type | Default | Description |
|
|
119
|
-
|--------|------|---------|-------------|
|
|
120
|
-
| `name` | `string` | -- | Helper name, used for scoped logging |
|
|
121
|
-
| `networkOptions.baseUrl` | `string` | `undefined` | Base URL prepended to all request paths |
|
|
122
|
-
| `networkOptions.headers` | `HeadersInit` | `{ 'content-type': 'application/json; charset=utf-8' }` | Default headers; supports `Headers` object or plain object |
|
|
123
|
-
| `networkOptions.*` | `RequestInit` | -- | All other `fetch` options are accepted |
|
|
124
|
-
|
|
125
|
-
### TCP Client / Server
|
|
126
|
-
|
|
127
|
-
#### TCP Client
|
|
128
|
-
|
|
129
|
-
```typescript
|
|
130
|
-
import { NetworkTcpClient } from '@venizia/ignis-helpers';
|
|
131
|
-
|
|
132
|
-
const tcpClient = new NetworkTcpClient({
|
|
133
|
-
identifier: 'sensor-reader',
|
|
134
|
-
options: {
|
|
135
|
-
host: 'localhost',
|
|
136
|
-
port: 8080,
|
|
137
|
-
},
|
|
138
|
-
reconnect: true,
|
|
139
|
-
maxRetry: 10,
|
|
140
|
-
encoding: 'utf8',
|
|
141
|
-
onConnected: ({ client }) => { console.log('Connected'); },
|
|
142
|
-
onData: ({ identifier, message }) => { console.log('Data:', message.toString()); },
|
|
143
|
-
onClosed: ({ client }) => { console.log('Closed'); },
|
|
144
|
-
onError: (error) => { console.error('Error:', error); },
|
|
145
|
-
});
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
#### TCP Client Options (`INetworkTcpClientProps`)
|
|
149
|
-
|
|
150
|
-
| Option | Type | Default | Description |
|
|
151
|
-
|--------|------|---------|-------------|
|
|
152
|
-
| `identifier` | `string` | -- | Unique client identifier for logging |
|
|
153
|
-
| `scope` | `string` | `identifier` | Logger scope name |
|
|
154
|
-
| `options` | `TcpSocketConnectOpts` | -- | Node.js `net.connect` options (`host`, `port`, etc.) |
|
|
155
|
-
| `reconnect` | `boolean` | `false` | Enable automatic reconnection on error |
|
|
156
|
-
| `maxRetry` | `number` | `5` | Maximum reconnection attempts |
|
|
157
|
-
| `encoding` | `BufferEncoding` | `undefined` | Socket encoding (e.g., `'utf8'`) |
|
|
158
|
-
| `onConnected` | `(opts: { client }) => void` | Internal logger | Called when connection is established |
|
|
159
|
-
| `onData` | `(opts: { identifier, message }) => void` | No-op | Called when data is received |
|
|
160
|
-
| `onClosed` | `(opts: { client }) => void` | Internal logger | Called when connection closes |
|
|
161
|
-
| `onError` | `(error: any) => void` | Internal handler with auto-reconnect | Called on connection errors |
|
|
162
|
-
|
|
163
|
-
#### TCP Server
|
|
164
|
-
|
|
165
|
-
```typescript
|
|
166
|
-
import { NetworkTcpServer } from '@venizia/ignis-helpers';
|
|
167
|
-
|
|
168
|
-
const tcpServer = new NetworkTcpServer({
|
|
169
|
-
identifier: 'my-tcp-server',
|
|
170
|
-
serverOptions: {},
|
|
171
|
-
listenOptions: { port: 8080, host: '0.0.0.0' },
|
|
172
|
-
authenticateOptions: { required: true, duration: 5000 },
|
|
173
|
-
onServerReady: ({ server }) => { console.log('Listening'); },
|
|
174
|
-
onClientConnected: ({ id, socket }) => { console.log(`Client ${id} connected`); },
|
|
175
|
-
onClientData: ({ id, socket, data }) => { console.log(`Data from ${id}:`, data.toString()); },
|
|
176
|
-
onClientClose: ({ id, socket }) => { console.log(`Client ${id} disconnected`); },
|
|
177
|
-
onClientError: ({ id, socket, error }) => { console.error(`Error from ${id}:`, error); },
|
|
178
|
-
});
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
> [!IMPORTANT]
|
|
182
|
-
> When `authenticateOptions.required` is `true`, you **must** provide a positive `duration` value. Clients that do not authenticate within this duration are automatically disconnected with an "Unauthorized Client" message. Use `doAuthenticate()` in your `onClientData` handler to transition the client's state.
|
|
34
|
+
`getRequestUrl()` joins the constructor's `baseUrl` with the path segments. `getNetworkService()` returns the underlying fetcher, which exposes `send()` plus `get`/`post`/`put`/`patch`/`delete`/`query` shortcuts.
|
|
183
35
|
|
|
184
|
-
|
|
36
|
+
## How it works
|
|
185
37
|
|
|
186
|
-
|
|
187
|
-
|--------|------|---------|-------------|
|
|
188
|
-
| `identifier` | `string` | -- | Server identifier for logging |
|
|
189
|
-
| `scope` | `string` | `identifier` | Logger scope name |
|
|
190
|
-
| `serverOptions` | `Partial<ServerOpts>` | -- | Node.js `net.Server` options |
|
|
191
|
-
| `listenOptions` | `Partial<ListenOptions>` | -- | Listen options (`port`, `host`, `backlog`, etc.) |
|
|
192
|
-
| `authenticateOptions.required` | `boolean` | -- | Whether clients must authenticate |
|
|
193
|
-
| `authenticateOptions.duration` | `number` | `undefined` | Auth timeout in ms (required when `required: true`) |
|
|
194
|
-
| `extraEvents` | `Record<string, (opts) => void>` | `{}` | Additional socket events to register per client |
|
|
195
|
-
| `onServerReady` | `(opts: { server }) => void` | `undefined` | Called when server starts listening |
|
|
196
|
-
| `onClientConnected` | `(opts: { id, socket }) => void` | `undefined` | Called on new client connection |
|
|
197
|
-
| `onClientData` | `(opts: { id, socket, data }) => void` | `undefined` | Called when data is received from a client |
|
|
198
|
-
| `onClientClose` | `(opts: { id, socket }) => void` | `undefined` | Called when a client disconnects |
|
|
199
|
-
| `onClientError` | `(opts: { id, socket, error }) => void` | `undefined` | Called on client socket error |
|
|
38
|
+
- **HTTP is two layers.** `BaseNetworkRequest` holds the base URL and delegates every call to an `IFetchable` fetcher. You extend one of two concrete clients:
|
|
200
39
|
|
|
201
|
-
|
|
40
|
+
| Client | Wraps | Import from |
|
|
41
|
+
|---|---|---|
|
|
42
|
+
| `NodeFetchNetworkRequest` | native `fetch` | root barrel |
|
|
43
|
+
| `AxiosNetworkRequest` | Axios | `@venizia/ignis-helpers/axios` sub-path |
|
|
202
44
|
|
|
203
|
-
|
|
45
|
+
- **`axios` is optional.** It is an optional peer dependency. `AxiosNetworkRequest` is exported only from the `/axios` sub-path, never from the root barrel.
|
|
46
|
+
- **TCP and TLS share one hierarchy.** `BaseNetworkTcpServer`/`BaseNetworkTcpClient` are abstract classes. Each takes a create-function matching its transport, and each concrete pair only pre-wires that function:
|
|
204
47
|
|
|
205
|
-
|
|
48
|
+
| Transport | Server class | Client class | Node module |
|
|
49
|
+
|---|---|---|---|
|
|
50
|
+
| Plain TCP | `NetworkTcpServer` | `NetworkTcpClient` | `net` |
|
|
51
|
+
| TLS | `NetworkTlsTcpServer` | `NetworkTlsTcpClient` | `tls` |
|
|
206
52
|
|
|
207
|
-
|
|
208
|
-
import { NetworkTlsTcpClient } from '@venizia/ignis-helpers';
|
|
209
|
-
import fs from 'node:fs';
|
|
210
|
-
|
|
211
|
-
const tlsClient = new NetworkTlsTcpClient({
|
|
212
|
-
identifier: 'secure-client',
|
|
213
|
-
options: {
|
|
214
|
-
host: 'secure.example.com',
|
|
215
|
-
port: 8443,
|
|
216
|
-
rejectUnauthorized: true,
|
|
217
|
-
ca: fs.readFileSync('ca.crt'),
|
|
218
|
-
cert: fs.readFileSync('client.crt'),
|
|
219
|
-
key: fs.readFileSync('client.key'),
|
|
220
|
-
},
|
|
221
|
-
reconnect: true,
|
|
222
|
-
maxRetry: 3,
|
|
223
|
-
onData: ({ message }) => { console.log('Secure data:', message); },
|
|
224
|
-
});
|
|
53
|
+
Constructor options and every method are otherwise identical between the plain and encrypted variants.
|
|
225
54
|
|
|
226
|
-
|
|
227
|
-
|
|
55
|
+
- **Servers track per-client authentication state.** `unauthorized` → `authenticating` → `authenticated`.
|
|
56
|
+
- **Clients auto-reconnect on a fixed delay.** 5 seconds between attempts, up to `maxRetry` attempts, when `reconnect: true`. See the [Full reference](/extensions/helpers/network/api) for the `maxRetry: -1` edge case.
|
|
57
|
+
- **UDP has no client/server split.** `NetworkUdpClient` is a single class wrapping `node:dgram` in UDP4 mode. It supports optional multicast group joining via `onBind`.
|
|
58
|
+
- **Every class extends `BaseHelper`.** `this.logger.for('methodName')` scoped logging is available throughout.
|
|
228
59
|
|
|
229
|
-
|
|
230
|
-
> `NetworkTlsTcpClient` accepts `ConnectionOptions` from `node:tls` in the `options` field. All other options (`reconnect`, `maxRetry`, callbacks) are identical to `NetworkTcpClient`.
|
|
60
|
+
**HTTP method case**
|
|
231
61
|
|
|
232
|
-
|
|
62
|
+
| Layer | Case | Why |
|
|
63
|
+
|-------|------|-----|
|
|
64
|
+
| `HTTP.Methods.GET`/`.POST`/`.QUERY`/... tokens | always lowercase | Required by `@hono/zod-openapi` route definitions |
|
|
65
|
+
| Wire dispatch | uppercased right before send | Node's undici only auto-normalizes `DELETE`/`GET`/`HEAD`/`OPTIONS`/`POST`/`PUT`. A lowercase `patch` or `query` would go out unchanged |
|
|
233
66
|
|
|
234
|
-
|
|
235
|
-
import { NetworkTlsTcpServer } from '@venizia/ignis-helpers';
|
|
236
|
-
import fs from 'node:fs';
|
|
237
|
-
|
|
238
|
-
const tlsServer = new NetworkTlsTcpServer({
|
|
239
|
-
identifier: 'secure-tcp-server',
|
|
240
|
-
serverOptions: {
|
|
241
|
-
cert: fs.readFileSync('server.crt'),
|
|
242
|
-
key: fs.readFileSync('server.key'),
|
|
243
|
-
ca: [fs.readFileSync('ca.crt')],
|
|
244
|
-
requestCert: true,
|
|
245
|
-
},
|
|
246
|
-
listenOptions: { port: 8443, host: '0.0.0.0' },
|
|
247
|
-
authenticateOptions: { required: false },
|
|
248
|
-
onClientData: ({ id, data }) => { console.log(`Secure data from ${id}:`, data.toString()); },
|
|
249
|
-
});
|
|
250
|
-
```
|
|
67
|
+
## Common tasks
|
|
251
68
|
|
|
252
|
-
|
|
253
|
-
> `NetworkTlsTcpServer` accepts `TlsOptions` from `node:tls` in `serverOptions`. All handlers and methods are identical to `NetworkTcpServer`.
|
|
69
|
+
### Use Axios instead of fetch
|
|
254
70
|
|
|
255
|
-
|
|
71
|
+
Import from the `/axios` sub-path - never from the root barrel, since `axios` is an optional peer dependency.
|
|
256
72
|
|
|
257
73
|
```typescript
|
|
258
|
-
import {
|
|
259
|
-
|
|
260
|
-
const udpClient = NetworkUdpClient.newInstance({
|
|
261
|
-
identifier: 'my-udp-client',
|
|
262
|
-
port: 8081,
|
|
263
|
-
host: '0.0.0.0',
|
|
264
|
-
reuseAddr: true,
|
|
265
|
-
multicastAddress: {
|
|
266
|
-
groups: ['239.1.2.3'],
|
|
267
|
-
interface: '0.0.0.0',
|
|
268
|
-
},
|
|
269
|
-
onData: ({ message, remoteInfo }) => {
|
|
270
|
-
console.log(`From ${remoteInfo.address}:${remoteInfo.port}:`, message.toString());
|
|
271
|
-
},
|
|
272
|
-
onBind: async ({ socket, multicastAddress }) => {
|
|
273
|
-
if (multicastAddress?.groups) {
|
|
274
|
-
for (const group of multicastAddress.groups) {
|
|
275
|
-
socket.addMembership(group, multicastAddress.interface);
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
},
|
|
279
|
-
});
|
|
280
|
-
```
|
|
281
|
-
|
|
282
|
-
#### UDP Client Options (`INetworkUdpClientProps`)
|
|
283
|
-
|
|
284
|
-
| Option | Type | Default | Description |
|
|
285
|
-
|--------|------|---------|-------------|
|
|
286
|
-
| `identifier` | `string` | -- | Unique client identifier for logging |
|
|
287
|
-
| `host` | `string` | `undefined` | Bind address |
|
|
288
|
-
| `port` | `number` | -- | Bind port |
|
|
289
|
-
| `reuseAddr` | `boolean` | `undefined` | Allow address reuse (`SO_REUSEADDR`) |
|
|
290
|
-
| `multicastAddress.groups` | `string[]` | `undefined` | Multicast group addresses to join |
|
|
291
|
-
| `multicastAddress.interface` | `string` | `undefined` | Network interface for multicast |
|
|
292
|
-
| `onConnected` | `(opts: { identifier, host?, port }) => void` | Internal logger | Called when socket starts listening |
|
|
293
|
-
| `onData` | `(opts: { identifier, message, remoteInfo }) => void` | Internal logger | Called when data is received |
|
|
294
|
-
| `onClosed` | `(opts: { identifier, host?, port }) => void` | Internal logger | Called when socket is closed |
|
|
295
|
-
| `onError` | `(opts: { identifier, host?, port, error }) => void` | Internal logger | Called on socket error |
|
|
296
|
-
| `onBind` | `(opts: { identifier, socket, host?, port, reuseAddr?, multicastAddress? }) => void` | `undefined` | Called after socket is bound; use to join multicast groups |
|
|
297
|
-
|
|
298
|
-
## Usage
|
|
299
|
-
|
|
300
|
-
### HTTP Requests
|
|
301
|
-
|
|
302
|
-
Access the underlying fetcher via `getNetworkService()`, then use `send()` or the convenience methods (`get`, `post`, `put`, `patch`, `delete`):
|
|
74
|
+
import { AxiosNetworkRequest } from '@venizia/ignis-helpers/axios';
|
|
303
75
|
|
|
304
|
-
```typescript
|
|
305
76
|
class PaymentGateway extends AxiosNetworkRequest {
|
|
306
77
|
constructor() {
|
|
307
78
|
super({
|
|
308
79
|
name: 'PaymentGateway',
|
|
309
80
|
networkOptions: {
|
|
310
|
-
baseUrl:
|
|
81
|
+
baseUrl: 'https://api.payments.com',
|
|
311
82
|
timeout: 30000,
|
|
312
83
|
headers: { 'X-API-Key': process.env.PAYMENT_API_KEY },
|
|
313
84
|
},
|
|
314
85
|
});
|
|
315
86
|
}
|
|
316
|
-
|
|
317
|
-
async charge(amount: number, currency: string) {
|
|
318
|
-
const url = this.getRequestUrl({ paths: ['v1', 'charges'] });
|
|
319
|
-
const response = await this.getNetworkService().send({
|
|
320
|
-
url,
|
|
321
|
-
method: 'post',
|
|
322
|
-
body: { amount, currency },
|
|
323
|
-
});
|
|
324
|
-
this.logger.for('charge').info('Payment processed: %s', response.data.id);
|
|
325
|
-
return response.data;
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
async getTransaction(id: string) {
|
|
329
|
-
const url = this.getRequestUrl({ paths: ['v1', 'transactions', id] });
|
|
330
|
-
return this.getNetworkService().get({ url });
|
|
331
|
-
}
|
|
332
87
|
}
|
|
333
88
|
```
|
|
334
89
|
|
|
335
|
-
|
|
90
|
+
`AxiosNetworkRequest` applies these defaults - override any of them in `networkOptions`:
|
|
336
91
|
|
|
337
|
-
|
|
92
|
+
| Setting | Default |
|
|
93
|
+
|---|---|
|
|
94
|
+
| `content-type` header | `application/json; charset=utf-8` |
|
|
95
|
+
| `withCredentials` | `true` |
|
|
96
|
+
| `validateStatus` | `status < 500` |
|
|
97
|
+
| `timeout` | `60000` ms |
|
|
338
98
|
|
|
339
|
-
|
|
99
|
+
### Log a request with secrets redacted
|
|
340
100
|
|
|
341
|
-
|
|
101
|
+
Pass a logger as the second argument to `send()` or any shortcut method - typically `this.logger` from a `BaseHelper` subclass. The fetcher then logs the URL and config at `info` level. It runs the config through `redactSecrets()` first, so values like `Authorization` or `X-API-Key` reach the log as `'[REDACTED]'`. Without a logger argument, nothing is logged.
|
|
342
102
|
|
|
343
103
|
```typescript
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
// All methods: get(), post(), put(), patch(), delete()
|
|
354
|
-
```
|
|
355
|
-
|
|
356
|
-
#### HTTPS with Axios
|
|
357
|
-
|
|
358
|
-
For HTTPS requests, the `AxiosFetcher` automatically creates an `https.Agent`. By default, `rejectUnauthorized` is `false`. Override it per request:
|
|
359
|
-
|
|
360
|
-
```typescript
|
|
361
|
-
await fetcher.send({
|
|
362
|
-
url: 'https://strict-api.example.com/data',
|
|
363
|
-
method: 'get',
|
|
364
|
-
rejectUnauthorized: true,
|
|
365
|
-
});
|
|
366
|
-
```
|
|
367
|
-
|
|
368
|
-
#### Timeout with Node Fetch
|
|
369
|
-
|
|
370
|
-
The `NodeFetcher` implements timeout via `AbortController`. Pass `timeout` in each `send()` call:
|
|
371
|
-
|
|
372
|
-
```typescript
|
|
373
|
-
await fetcher.send({
|
|
374
|
-
url: '/slow-endpoint',
|
|
375
|
-
method: 'get',
|
|
376
|
-
timeout: 5000, // Aborts after 5 seconds
|
|
377
|
-
});
|
|
104
|
+
async charge(amount: number, currency: string) {
|
|
105
|
+
const url = this.getRequestUrl({ paths: ['v1', 'charges'] });
|
|
106
|
+
const response = await this.getNetworkService().post(
|
|
107
|
+
{ url, body: { amount, currency } },
|
|
108
|
+
this.logger,
|
|
109
|
+
);
|
|
110
|
+
return response.data;
|
|
111
|
+
}
|
|
378
112
|
```
|
|
379
113
|
|
|
380
|
-
### TCP
|
|
114
|
+
### Open a TCP connection
|
|
381
115
|
|
|
382
116
|
```typescript
|
|
383
117
|
import { NetworkTcpClient, NetworkTcpServer } from '@venizia/ignis-helpers';
|
|
384
118
|
|
|
385
|
-
// --- Server ---
|
|
386
119
|
const server = new NetworkTcpServer({
|
|
387
120
|
identifier: 'echo-server',
|
|
388
121
|
serverOptions: {},
|
|
389
122
|
listenOptions: { port: 9000, host: '0.0.0.0' },
|
|
390
123
|
authenticateOptions: { required: false },
|
|
391
|
-
onClientData: ({ id, data }) => {
|
|
392
|
-
// Echo back to the sender
|
|
393
|
-
server.emit({ clientId: id, payload: data });
|
|
394
|
-
},
|
|
124
|
+
onClientData: ({ id, data }) => server.emit({ clientId: id, payload: data }),
|
|
395
125
|
});
|
|
396
126
|
|
|
397
|
-
// --- Client ---
|
|
398
127
|
const client = new NetworkTcpClient({
|
|
399
128
|
identifier: 'echo-client',
|
|
400
129
|
options: { host: 'localhost', port: 9000 },
|
|
401
130
|
reconnect: true,
|
|
402
131
|
maxRetry: 5,
|
|
403
|
-
|
|
404
|
-
onData: ({ message }) => { console.log('Echo:', message); },
|
|
132
|
+
onData: ({ message }) => console.log('Echo:', message),
|
|
405
133
|
});
|
|
406
134
|
|
|
407
135
|
client.connect({ resetReconnectCounter: true });
|
|
408
136
|
client.emit({ payload: 'Hello, Server!' });
|
|
409
137
|
```
|
|
410
138
|
|
|
411
|
-
|
|
139
|
+
`NetworkTlsTcpServer`/`NetworkTlsTcpClient` use the identical API. Pass certificates in `serverOptions`/`options`, typed `TlsOptions`/`ConnectionOptions` from `node:tls`.
|
|
140
|
+
|
|
141
|
+
### Require TCP client authentication
|
|
142
|
+
|
|
143
|
+
Set `authenticateOptions.required: true` with a positive `duration` in milliseconds. The constructor throws if `duration` is missing or negative. Clients that never call `doAuthenticate()` within that window are disconnected automatically.
|
|
412
144
|
|
|
413
145
|
```typescript
|
|
414
146
|
const server = new NetworkTcpServer({
|
|
415
|
-
identifier: 'auth-
|
|
147
|
+
identifier: 'auth-server',
|
|
416
148
|
serverOptions: {},
|
|
417
149
|
listenOptions: { port: 9000, host: '0.0.0.0' },
|
|
418
150
|
authenticateOptions: { required: true, duration: 5000 },
|
|
419
|
-
|
|
420
151
|
onClientData: ({ id, data }) => {
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
if (client?.state === 'unauthorized') {
|
|
425
|
-
if (message === 'secret-token') {
|
|
426
|
-
server.doAuthenticate({ id, state: 'authenticated' });
|
|
427
|
-
server.emit({ clientId: id, payload: 'Authenticated!' });
|
|
428
|
-
} else {
|
|
429
|
-
server.emit({ clientId: id, payload: 'Invalid credentials' });
|
|
430
|
-
}
|
|
431
|
-
return;
|
|
152
|
+
if (data.toString() === 'secret-token') {
|
|
153
|
+
server.doAuthenticate({ id, state: 'authenticated' });
|
|
432
154
|
}
|
|
433
|
-
|
|
434
|
-
// Handle authenticated client messages
|
|
435
|
-
console.log(`[${id}] ${message}`);
|
|
436
155
|
},
|
|
437
156
|
});
|
|
438
157
|
```
|
|
439
158
|
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
Each connected client is tracked as an `ITcpSocketClient`:
|
|
443
|
-
|
|
444
|
-
```typescript
|
|
445
|
-
interface ITcpSocketClient<SocketClientType> {
|
|
446
|
-
id: string;
|
|
447
|
-
socket: SocketClientType;
|
|
448
|
-
state: 'unauthorized' | 'authenticating' | 'authenticated';
|
|
449
|
-
subscriptions: Set<string>;
|
|
450
|
-
storage: {
|
|
451
|
-
connectedAt: dayjs.Dayjs;
|
|
452
|
-
authenticatedAt: dayjs.Dayjs | null;
|
|
453
|
-
[additionField: symbol | string]: any; // Extensible storage
|
|
454
|
-
};
|
|
455
|
-
}
|
|
456
|
-
```
|
|
457
|
-
|
|
458
|
-
### TLS Encrypted Communication
|
|
459
|
-
|
|
460
|
-
TLS classes share the same API as their TCP counterparts. Provide TLS certificates in the `options` or `serverOptions` field:
|
|
461
|
-
|
|
462
|
-
```typescript
|
|
463
|
-
import { NetworkTlsTcpServer, NetworkTlsTcpClient } from '@venizia/ignis-helpers';
|
|
464
|
-
import fs from 'node:fs';
|
|
465
|
-
|
|
466
|
-
// --- TLS Server ---
|
|
467
|
-
const tlsServer = new NetworkTlsTcpServer({
|
|
468
|
-
identifier: 'secure-server',
|
|
469
|
-
serverOptions: {
|
|
470
|
-
cert: fs.readFileSync('server.crt'),
|
|
471
|
-
key: fs.readFileSync('server.key'),
|
|
472
|
-
ca: [fs.readFileSync('ca.crt')],
|
|
473
|
-
requestCert: true,
|
|
474
|
-
},
|
|
475
|
-
listenOptions: { port: 8443, host: '0.0.0.0' },
|
|
476
|
-
authenticateOptions: { required: false },
|
|
477
|
-
onClientData: ({ id, data }) => {
|
|
478
|
-
console.log(`Secure data from ${id}:`, data.toString());
|
|
479
|
-
},
|
|
480
|
-
});
|
|
481
|
-
|
|
482
|
-
// --- TLS Client ---
|
|
483
|
-
const tlsClient = new NetworkTlsTcpClient({
|
|
484
|
-
identifier: 'secure-client',
|
|
485
|
-
options: {
|
|
486
|
-
host: 'localhost',
|
|
487
|
-
port: 8443,
|
|
488
|
-
rejectUnauthorized: true,
|
|
489
|
-
ca: fs.readFileSync('ca.crt'),
|
|
490
|
-
cert: fs.readFileSync('client.crt'),
|
|
491
|
-
key: fs.readFileSync('client.key'),
|
|
492
|
-
},
|
|
493
|
-
onData: ({ message }) => { console.log('Secure:', message); },
|
|
494
|
-
});
|
|
495
|
-
|
|
496
|
-
tlsClient.connect({ resetReconnectCounter: true });
|
|
497
|
-
tlsClient.emit({ payload: 'Hello over TLS!' });
|
|
498
|
-
```
|
|
499
|
-
|
|
500
|
-
### UDP Communication
|
|
159
|
+
### Send a UDP datagram
|
|
501
160
|
|
|
502
161
|
```typescript
|
|
503
162
|
import { NetworkUdpClient } from '@venizia/ignis-helpers';
|
|
504
163
|
|
|
505
164
|
const udpClient = NetworkUdpClient.newInstance({
|
|
506
|
-
identifier: '
|
|
507
|
-
port:
|
|
165
|
+
identifier: 'my-udp-client',
|
|
166
|
+
port: 8081,
|
|
508
167
|
host: '0.0.0.0',
|
|
509
|
-
reuseAddr: true,
|
|
510
|
-
multicastAddress: {
|
|
511
|
-
groups: ['239.1.2.3'],
|
|
512
|
-
interface: '0.0.0.0',
|
|
513
|
-
},
|
|
514
168
|
onData: ({ message, remoteInfo }) => {
|
|
515
169
|
console.log(`From ${remoteInfo.address}:${remoteInfo.port}:`, message.toString());
|
|
516
170
|
},
|
|
517
|
-
onBind: async ({ socket, multicastAddress }) => {
|
|
518
|
-
// Join multicast groups after socket is bound
|
|
519
|
-
if (multicastAddress?.groups) {
|
|
520
|
-
for (const group of multicastAddress.groups) {
|
|
521
|
-
socket.addMembership(group, multicastAddress.interface);
|
|
522
|
-
}
|
|
523
|
-
}
|
|
524
|
-
},
|
|
525
171
|
});
|
|
526
172
|
|
|
527
|
-
// Start listening
|
|
528
173
|
udpClient.connect();
|
|
529
|
-
|
|
530
|
-
// Access the underlying dgram.Socket
|
|
531
|
-
const socket = udpClient.getClient();
|
|
532
|
-
|
|
533
|
-
// Check if bound
|
|
534
|
-
if (udpClient.isConnected()) {
|
|
535
|
-
// Send a datagram via the raw socket
|
|
536
|
-
socket.send('Hello', 5001, '239.1.2.3');
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
// Stop listening
|
|
540
|
-
udpClient.disconnect();
|
|
541
|
-
```
|
|
542
|
-
|
|
543
|
-
## Troubleshooting
|
|
544
|
-
|
|
545
|
-
### HTTP: "[getRequestUrl] Invalid configuration for third party request base url!"
|
|
546
|
-
|
|
547
|
-
**Cause:** `getRequestUrl()` was called but no `baseUrl` was provided at construction time or in the call's `opts.baseUrl` parameter.
|
|
548
|
-
|
|
549
|
-
**Fix:** Provide a `baseUrl` either in the constructor's `networkOptions` or pass it in the `opts` parameter of `getRequestUrl()`:
|
|
550
|
-
|
|
551
|
-
```typescript
|
|
552
|
-
// At construction
|
|
553
|
-
const client = new AxiosNetworkRequest({
|
|
554
|
-
name: 'MyClient',
|
|
555
|
-
networkOptions: { baseUrl: 'https://api.example.com' },
|
|
556
|
-
});
|
|
557
|
-
|
|
558
|
-
// Or per call
|
|
559
|
-
const url = client.getRequestUrl({
|
|
560
|
-
baseUrl: 'https://api.example.com',
|
|
561
|
-
paths: ['v1', 'users'],
|
|
562
|
-
});
|
|
563
|
-
```
|
|
564
|
-
|
|
565
|
-
### HTTP: Timeout not working with NodeFetchNetworkRequest
|
|
566
|
-
|
|
567
|
-
**Cause:** The `timeout` option on the constructor's `networkOptions` is not automatically applied to individual requests. Timeout must be set per-request.
|
|
568
|
-
|
|
569
|
-
**Fix:** Pass `timeout` in each `send()` call:
|
|
570
|
-
|
|
571
|
-
```typescript
|
|
572
|
-
await this.getNetworkService().send({
|
|
573
|
-
url: '/slow-endpoint',
|
|
574
|
-
method: 'get',
|
|
575
|
-
timeout: 5000,
|
|
576
|
-
});
|
|
174
|
+
udpClient.getClient()?.send('Hello', 5001, '239.1.2.3');
|
|
577
175
|
```
|
|
578
176
|
|
|
579
|
-
|
|
177
|
+
## See also
|
|
580
178
|
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
**Cause:** `authenticateOptions.required` is `true` but `duration` is missing, zero, or negative.
|
|
584
|
-
|
|
585
|
-
**Fix:** Provide a positive `duration` value when authentication is required:
|
|
586
|
-
|
|
587
|
-
```typescript
|
|
588
|
-
// Correct
|
|
589
|
-
authenticateOptions: { required: true, duration: 5000 }
|
|
590
|
-
|
|
591
|
-
// Wrong -- throws at construction time
|
|
592
|
-
authenticateOptions: { required: true }
|
|
593
|
-
authenticateOptions: { required: true, duration: -1 }
|
|
594
|
-
```
|
|
595
|
-
|
|
596
|
-
### TCP Client: Reconnect loop never stops
|
|
597
|
-
|
|
598
|
-
**Cause:** `maxRetry` is set to `-1` (infinite retries) and the target server is unreachable. The reconnect delay is fixed at 5 seconds between attempts.
|
|
599
|
-
|
|
600
|
-
**Fix:** Use a finite `maxRetry` value, or set `reconnect: false` if you handle reconnection externally:
|
|
601
|
-
|
|
602
|
-
```typescript
|
|
603
|
-
const client = new NetworkTcpClient({
|
|
604
|
-
identifier: 'my-client',
|
|
605
|
-
options: { host: 'localhost', port: 8080 },
|
|
606
|
-
reconnect: true,
|
|
607
|
-
maxRetry: 5, // Stop after 5 attempts
|
|
608
|
-
});
|
|
609
|
-
```
|
|
610
|
-
|
|
611
|
-
### TCP Server: Client emit does nothing
|
|
612
|
-
|
|
613
|
-
**Cause:** The target client socket is not writable (already closed or half-closed), or the payload is empty. The server logs a warning but does not throw.
|
|
614
|
-
|
|
615
|
-
**Fix:** Check the client state before emitting:
|
|
616
|
-
|
|
617
|
-
```typescript
|
|
618
|
-
const client = server.getClient({ id: clientId });
|
|
619
|
-
if (client && client.socket.writable) {
|
|
620
|
-
server.emit({ clientId, payload: 'Hello' });
|
|
621
|
-
}
|
|
622
|
-
```
|
|
179
|
+
- [Full reference](/extensions/helpers/network/api) - every class, method signature, and type in the module
|
|
180
|
+
- [Redis helper](/extensions/helpers/redis/) - another `BaseHelper`-based connection helper with the same scoped-logging conventions
|
|
623
181
|
|
|
624
|
-
|
|
182
|
+
**Files:**
|
|
625
183
|
|
|
626
|
-
- [
|
|
184
|
+
- [`packages/helpers/src/modules/network/http-request/base-network-request.helper.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/network/http-request/base-network-request.helper.ts) - `BaseNetworkRequest`
|
|
185
|
+
- [`packages/helpers/src/modules/network/http-request/fetcher/node-fetcher.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/network/http-request/fetcher/node-fetcher.ts) - `NodeFetcher`, `NodeFetchNetworkRequest`
|
|
186
|
+
- [`packages/helpers/src/modules/network/http-request/fetcher/axios-fetcher.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/network/http-request/fetcher/axios-fetcher.ts) - `AxiosFetcher`, `AxiosNetworkRequest` (sub-path export)
|
|
187
|
+
- [`packages/helpers/src/modules/network/tcp-socket/base-tcp-server.helper.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/network/tcp-socket/base-tcp-server.helper.ts) - `BaseNetworkTcpServer`
|
|
188
|
+
- [`packages/helpers/src/modules/network/tcp-socket/base-tcp-client.helper.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/network/tcp-socket/base-tcp-client.helper.ts) - `BaseNetworkTcpClient`
|
|
189
|
+
- [`packages/helpers/src/modules/network/udp-socket/network-udp-client.helper.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/network/udp-socket/network-udp-client.helper.ts) - `NetworkUdpClient`
|