samanbayaka 0.0.13 → 0.0.14

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 CHANGED
@@ -30,6 +30,10 @@ This project is a modular, production-ready microservices framework built with M
30
30
  ```bash
31
31
  pnpm install samanbayaka
32
32
  ```
33
+ Once the package is installed, you can import the library using import or require approach:
34
+ ```bash
35
+ import sbk from "samanbayaka"
36
+ ```
33
37
  # Prerequisites
34
38
  It is assumed that NATS, Redpanda, and Redis are installed and properly configured. All services should be discoverable through the /etc/hosts file.
35
39
  #### Minimum required Node.js version: >= 22.x.x
@@ -37,6 +41,7 @@ It is assumed that NATS, Redpanda, and Redis are installed and properly configur
37
41
  node -v
38
42
  nvm use 22
39
43
  ```
44
+ Additionally, OpenObserve is used to view logs and telemetry.
40
45
 
41
46
  #### Environment variables
42
47
  To configure all required environment variables, create a Bash file:
@@ -45,14 +50,23 @@ sudo nano /etc/logrotate.d/sbk.sh
45
50
  ```
46
51
  Paste this:
47
52
  ```bash
48
- ##Configurations files path
53
+ ## Configurations files path
49
54
  export SBK_CONFIG_PATH=/usr/local/etc/<your_folder>
50
55
 
51
- ##web server port 8760-8769
56
+ ## Web server port 8760-8769
52
57
  export SBK_PORT=8765
53
58
 
54
- ##Log level allowed values are fatal | error | warn | info | debug | trace
55
- export SBK_LOG_LEVEL=debug
59
+ ## Log level allowed values are fatal | error | warn | info | debug | trace
60
+ export SBK_LOG_LEVEL=info
61
+
62
+ ## Maximum allowed TTL for the memoryLRU (L1) cache; the value is capped at 600 seconds.
63
+ export MAX_L1_TTL=120
64
+
65
+ ## Maximum allowed TTL for the redis (L2) cache; the value is capped at 86400 seconds.
66
+ export MAX_L2_TTL=600
67
+
68
+ ## Enabling telemetry middleware – Set the value to true; the default is false.
69
+ export SBK_TELEMETRY_ENABLE=false
56
70
  ```
57
71
  Set environment variables in the current Bash session.
58
72
  ```bash
@@ -98,6 +112,138 @@ Paste this:
98
112
  create 0640 node node
99
113
  }
100
114
  ```
115
+
116
+ ## API Docs
117
+
118
+ ### sbk.Errors
119
+
120
+ `sbk.Errors` exposes the Moleculer `Errors` object.
121
+
122
+ ### sbk.getConfig
123
+
124
+ `sbk.getConfig` is a function that returns a configuration object from a specified file name.
125
+
126
+ The file is loaded from the configuration directory defined by the environment variable.
127
+
128
+ ### sbk.loadDemo
129
+
130
+ `sbk.loadDemo` is an asynchronous function that creates a demo service to help understand the project.
131
+
132
+ ### sbk.loadGatewayService
133
+
134
+ `sbk.loadGatewayService` is an asynchronous function that creates a gateway service to expose REST APIs.
135
+
136
+ ### sbk.loadFeatureService
137
+
138
+ `sbk.loadFeatureService` is an asynchronous function that creates a feature service.
139
+
140
+ ##### Function Signature
141
+
142
+ ```js
143
+ sbk.loadFeatureService(schema)
144
+ ```
145
+
146
+ ##### Parameter
147
+
148
+ * `schema` - An object that follows the Moleculer service schema structure.
149
+
150
+ Example:
151
+
152
+ ```js
153
+ {
154
+ name: "math",
155
+ actions: {
156
+ add(ctx) {
157
+ return Number(ctx.params.a) + Number(ctx.params.b);
158
+ },
159
+
160
+ sub(ctx) {
161
+ return Number(ctx.params.a) - Number(ctx.params.b);
162
+ }
163
+ }
164
+ }
165
+ ```
166
+
167
+
168
+ ### sbk.auxBrokerService
169
+
170
+ `sbk.auxBrokerService` is a function used to initialize and manage message brokers such as Kafka, MQTT, and RabbitMQ.
171
+
172
+ ##### Function Signature
173
+
174
+ ```js
175
+ sbk.auxBrokerService(
176
+ type,
177
+ brokerOpts = {},
178
+ callback = () => {}
179
+ )
180
+ ```
181
+ ##### Parameters
182
+
183
+ * `type` *(string)* - Specifies the broker type to initialize. Supported values:
184
+
185
+ * `"kafka"`
186
+ * `"mqtt"`
187
+ * `"amqp"`
188
+
189
+ Example:
190
+
191
+ ```js
192
+ "kafka"
193
+ ```
194
+
195
+
196
+ * `brokerOpts` *(object)* - Configuration object used to initialize the broker client, producer, and consumer. Example structure:
197
+
198
+ ```js
199
+ {
200
+ name: <your_service_name>
201
+ client: {},
202
+ producer: {},
203
+ consumer: {
204
+ groupId: "all",
205
+ interMessageDelayMs: 10,
206
+ },
207
+ logLevel: "INFO",
208
+ gzip: true,
209
+ msgPack: true,
210
+ rest: false,
211
+ }
212
+ ```
213
+
214
+ Configuration Options
215
+
216
+ | Property | Type | Description |
217
+ |---|---|---|
218
+ | `name` | `string` | Only lowercase letters (a–z), digits (0–9), and hyphens (-) are allowed. |
219
+ | `client` | `object` | Broker client configuration |
220
+ | `producer` | `object` | Producer configuration |
221
+ | `consumer` | `object` | Consumer configuration |
222
+ | `consumer.groupId` | `string` | Consumer group identifier is mandatory for the consumer |
223
+ | `consumer.interMessageDelayMs` | `number` | Optional delay between messages in milliseconds |
224
+ | `logLevel` | `string` | Logging level (`NOTHING`, `ERROR`, `WARN`, `INFO`, `DEBUG`), default `NOTHING` |
225
+ | `gzip` | `boolean` | Enables message compression; only GZIP is supported, default `true` |
226
+ | `msgPack` | `boolean` | Enables MessagePack serialization, default `true` |
227
+ | `rest` | `boolean` | Enables REST end point, default `false` |
228
+
229
+
230
+ * `callback` *(function)* - Callback function executed when a message/event is received.
231
+
232
+ Arguments
233
+
234
+ | Argument | Description |
235
+ |---|---|
236
+ | `ctx` | Broker context |
237
+ | `payload` | Incoming message payload |
238
+
239
+ Example:
240
+
241
+ ```js
242
+ (ctx, payload) => {
243
+ ctx.broker.logger.debug(payload)
244
+ }
245
+ ```
246
+
101
247
  # Usage
102
248
  #### Create gateway service
103
249
  The Gateway is a critical service that exposes all endpoints as REST APIs. At least one Gateway service must be running to make the REST APIs accessible.
@@ -114,7 +260,8 @@ Open index.mjs and paste the following:
114
260
  import sbk from "samanbayaka"
115
261
  await sbk.loadGatewayService()
116
262
  ```
117
- #### Create feature service
263
+ ---
264
+ #### Create feature services
118
265
  ```bash
119
266
  mkdir <your_service_name>
120
267
  cd <your_service_name>
@@ -123,7 +270,7 @@ pnpm install samanbayaka
123
270
  touch index.mjs
124
271
  ```
125
272
 
126
- A feature service, such as "hello", can be created as follows:
273
+ A feature service, such as `hello`, can be created as follows:
127
274
  ```bash
128
275
  mkdir hello
129
276
  cd hello
@@ -135,7 +282,7 @@ touch index.mjs
135
282
  Open index.mjs and paste the following:
136
283
  ```bash
137
284
  import sbk from "samanbayaka"
138
- await sbk.loadFeatureService.mainBus({
285
+ await sbk.loadFeatureService({
139
286
  name: "hello",
140
287
  version: "v1",
141
288
 
@@ -152,7 +299,9 @@ await sbk.loadFeatureService.mainBus({
152
299
  cache: {
153
300
 
154
301
  /**
155
- * These cache entries will be expired after 30 seconds.
302
+ * Cache entries expire after 30 seconds.
303
+ * For L1 caching, TTL should be defined as [L2_TTL, L1_TTL].
304
+ * Example: ttl: [60, 10] → L2 TTL is 60 seconds and L1 TTL is 10 seconds.
156
305
  */
157
306
  ttl: 30
158
307
  },
@@ -169,8 +318,87 @@ await sbk.loadFeatureService.mainBus({
169
318
  },
170
319
  })
171
320
 
321
+ ```
322
+ ---
323
+ #### Create auxaliary broker services
324
+ ##### for producer
325
+ ```bash
326
+ mkdir <your_service_name>-<type>-<topic>
327
+ cd <your_service_name>-<type>-<topic>
328
+ npm init -y
329
+ pnpm install samanbayaka
330
+ touch index.mjs
331
+ ```
332
+ An auxiliary service, such as a `producer` that publishes messages to the `STUDENT` topic, can be created as follows:
333
+ ```js
334
+ mkdir producer-kafka-student
335
+ cd producer-kafka-student
336
+ npm init -y
337
+ pnpm install samanbayaka
338
+ touch index.mjs
339
+ ```
340
+
341
+ Open index.mjs and paste the following:
342
+ ```bash
343
+ import sbk from "samanbayaka"
344
+ await sbk.auxBrokerService(
345
+ "kafka",
346
+ {
347
+ name: "producer-kafka-student",
348
+ rest: true,
349
+ ...
350
+ },
351
+ () => {}
352
+ )
353
+ ```
354
+ In the service configuration `name` end with "`*`" i.e. `producer-kafka-student*` can capable to publish to the all topics start with `STUDENT` like `STUDENT.SCIENCE`, `STUDENT.ARTS` etc.
355
+ ```js
356
+ name: "producer-kafka-student*"
357
+ ```
358
+
359
+ If you do not expose the service as a REST API and run it as a private/internal service, either remove the `rest` property or set it to `false`.
360
+ ```js
361
+ rest: false
172
362
  ```
173
363
 
364
+ ##### for consumer
365
+ ```bash
366
+ mkdir <your_service_name>-<type>-<topic>-<group>
367
+ cd <your_service_name>-<type>-<topic>-<group>
368
+ npm init -y
369
+ pnpm install samanbayaka
370
+ touch index.mjs
371
+ ```
372
+ An auxiliary service, such as a `consumer` that subscribe messages from the `STUDENT` topic having group name `junior`, can be created as follows:
373
+ ```js
374
+ mkdir producer-kafka-student-junior
375
+ cd producer-kafka-student-junior
376
+ npm init -y
377
+ pnpm install samanbayaka
378
+ touch index.mjs
379
+ ```
380
+ Open index.mjs and paste the following:
381
+ ```bash
382
+ import sbk from "samanbayaka"
383
+ await sbk.auxBrokerService(
384
+ "kafka",
385
+ {
386
+ name: "consumer-kafka-student",
387
+ consumer: {
388
+ groupId: "junior",
389
+ interMessageDelayMs: 10,
390
+ ...
391
+ },
392
+ ...
393
+ },
394
+ () => {}
395
+ )
396
+ ```
397
+ The `interMessageDelayMs` option introduces a delay between two consecutive message/event consumptions, measured in milliseconds. If you do not need any delay between message consumption, simply remove the `interMessageDelayMs` property from the consumer options.
398
+
399
+
400
+ ---
401
+
174
402
  #### Run the services
175
403
 
176
404
  * development/testing
@@ -207,9 +435,6 @@ Run the service, demo
207
435
  node demo.mjs
208
436
  ```
209
437
 
210
-
211
-
212
-
213
438
  <p align="center" style="margin-top: 100px;">
214
439
  <img src="https://moleculer.services/images/banner.png" alt="Moleculer Logo" width="600">
215
440
  </p>
package/commit-hash.mjs CHANGED
@@ -1 +1 @@
1
- export const COMMIT_HASH = '289c98a';
1
+ export const COMMIT_HASH = '782e7c8';
@@ -0,0 +1,27 @@
1
+ /*catcher.mjs*/
2
+ export default {
3
+ /**
4
+ * Maximum items
5
+ */
6
+ max: 200,
7
+
8
+ /**
9
+ * Time-to-Live in seconds
10
+ */
11
+ ttl: [600, 120],
12
+
13
+ redis: {
14
+ /**
15
+ * Turns Redis client monitoring on.
16
+ */
17
+ monitor: false,
18
+
19
+ /**
20
+ * Redis settings like hostname, port, password
21
+ */
22
+ host: "redis",
23
+ port: 6379,
24
+ // password: "1234",
25
+ // db: 0,
26
+ }
27
+ }
@@ -1,54 +1,66 @@
1
- /*kafkajs.mjs*/
2
- // export default Object.freeze({
3
- // prefix: "SBK",
4
- // client: {
5
- // clientId: "moleculer-kafkajs",
6
- // brokers: ["redpanda:9092"],
7
- // connectionTimeout: 3000,
8
- // requestTimeout: 25000,
9
- // enforceRequestTimeout: false,
10
- // retry: {
11
- // maxRetryTime: 30000,
12
- // initialRetryTime: 300,
13
- // factor: 0.2,
14
- // multiplier: 2,
15
- // retries: 5
16
- // },
17
- // producer: {
18
- // idempotent: true,
19
- // maxInFlightRequests: 1,
20
- // },
21
- // logLevel: "INFO",
22
- // }
23
- // })
24
-
25
-
26
- export default Object.freeze({
27
- type: "Kafka",
28
- options: {
29
- // host: "localhost:9092", // Your Kafka broker address
30
- client: {
31
- clientId: "moleculer-cluster",
32
- brokers: ["redpanda:9092"],
33
- connectionTimeout: 3000,
34
- requestTimeout: 25000,
35
- enforceRequestTimeout: false,
36
- retry: {
37
- maxRetryTime: 30000,
38
- initialRetryTime: 300,
39
- factor: 0.2,
40
- multiplier: 2,
41
- retries: 5
42
- }
1
+ export default {
2
+ client: {
3
+ clientId: "node-client123",
4
+ brokers: ["pnsntst.wbsedcl.in:9092"],
5
+ connectionTimeout: 20000,
6
+ requestTimeout: 20000,
7
+ enforceRequestTimeout: true,
8
+ retry: {
9
+ maxRetryTime: 60000,
10
+ initialRetryTime: 300,
11
+ factor: 0.2,
12
+ multiplier: 2,
13
+ retries: 5
43
14
  },
44
- producer: {
45
- idempotent: true,
46
- maxInFlightRequests: 1,
15
+ ssl: {
16
+ rejectUnauthorized: true,
47
17
  },
48
- consumer: {
49
- groupId: "moleculer-group"
18
+ sasl: {
19
+ mechanism: "scram-sha-256",
20
+ username: "bob",
21
+ password: "SUhcznwt0xopsTfDXKIPzgw66dzJpZ",
22
+ },
23
+ },
24
+ producer: {
25
+ retry: {
26
+ initialRetryTime: 300,
27
+ // retries: Number.MAX_SAFE_INTEGER
28
+ retries: 8,
29
+ maxRetryTime: 30000,
30
+ factor: 0.2,
31
+ multiplier: 2
50
32
  },
51
- logLevel: "INFO",
52
- }
53
- // Ensure protocol v5 is active (default in 0.15.0-beta1)
54
- })
33
+ metadataMaxAge: 300000,
34
+ allowAutoTopicCreation: false,
35
+ transactionTimeout: 30000,
36
+ idempotent: true,
37
+ maxInFlightRequests: 1,
38
+ },
39
+ consumer: {
40
+ groupId: "default",
41
+ // partitionAssigners: <Array>,
42
+ sessionTimeout: 30000,
43
+ rebalanceTimeout: 60000,
44
+ heartbeatInterval: 5000,
45
+ metadataMaxAge: 300000,
46
+ allowAutoTopicCreation: false,
47
+ maxBytesPerPartition: 1048576, // 1 MB
48
+ minBytes: 1,
49
+ maxBytes: 10485760, // 10 MB
50
+ maxWaitTimeInMs: 5000,
51
+ retry: {
52
+ initialRetryTime: 300,
53
+ retries: 8,
54
+ maxRetryTime: 30000,
55
+ factor: 0.2,
56
+ multiplier: 2
57
+ },
58
+ maxInFlightRequests: 1,
59
+ // rackId: <String>,
60
+ // interMessageDelayMs: 10,
61
+ },
62
+ logLevel: "INFO",
63
+ gzip: true,
64
+ msgPack: true,
65
+ rest: false,
66
+ }
package/config/nats.mjs CHANGED
@@ -1,26 +1,189 @@
1
- /*nats.mjs*/
2
- export default Object.freeze({
3
- type: "NATS",
4
- options: {
5
- /**
6
- * High availability
7
- */
8
- servers: [
9
- "nats://nats:4222",
10
- ],
11
-
12
- /**
13
- * Reconnect settings
14
- */
15
- reconnect: true,
16
- maxReconnectAttempts: -1,
17
- reconnectTimeWait: 2000,
18
-
19
- /**
20
- * Performance
21
- */
22
- maxInFlight: 1000,
23
- timeout: 5000,
1
+ /*broker.mjs*/
24
2
 
3
+ export default {
4
+ /**
5
+ * Namespace of nodes to segment your nodes on the same network
6
+ */
7
+ namespace: "sbk",
8
+
9
+ /**
10
+ * Timeouts
11
+ */
12
+ requestTimeout: 10 * 1000,
13
+
14
+ /**
15
+ * Retry policy
16
+ */
17
+ retryPolicy: {
18
+ enabled: true,
19
+ retries: 3,
20
+ delay: 200,
21
+ maxDelay: 3000,
22
+ factor: 2,
23
+ check: err => err && !!err.retryable
24
+ },
25
+
26
+ /**
27
+ * Controls whether ctx.params is cloned or passed by reference
28
+ */
29
+ contextParamsCloning: false,
30
+
31
+ /**
32
+ * Limits nested service call depth
33
+ */
34
+ maxCallLevel: 100,
35
+
36
+ /**
37
+ * How often (seconds) a node sends heartbeat signals
38
+ */
39
+ heartbeatInterval: 5,
40
+ heartbeatTimeout: 20,
41
+
42
+ /**
43
+ * When your service shuts down
44
+ */
45
+ tracking: {
46
+ enabled: true,
47
+ shutdownTimeout: 10 * 1000,
48
+ },
49
+
50
+ /**
51
+ * Controls whether Moleculer’s built-in load balancer is used
52
+ */
53
+ disableBalancer: false,
54
+
55
+ /**
56
+ * Load balancing
57
+ */
58
+ registry: {
59
+ strategy: "RoundRobin",
60
+ preferLocal: true
61
+ },
62
+
63
+ /**
64
+ * Circuit breaker in Moleculer—a critical pattern to prevent
65
+ * cascading failures in distributed systems
66
+ */
67
+ circuitBreaker: {
68
+ enabled: true,
69
+ threshold: 0.5,
70
+ minRequestCount: 50,
71
+ windowTime: 60,
72
+ halfOpenTime: 10 * 1000
73
+ },
74
+
75
+ /**
76
+ * Bulkhead (prevent overload)
77
+ */
78
+ bulkhead: {
79
+ enabled: true,
80
+ concurrency: 50,
81
+ maxQueueSize: 200
82
+ },
83
+
84
+ /**
85
+ * Metrics (optional but recommended)
86
+ */
87
+ metrics: {
88
+ enabled: false,
89
+ // reporter: [
90
+ // {
91
+ // type: "Prometheus",
92
+ // options: {
93
+ // port: 3030
94
+ // }
95
+ // }
96
+ // ]
97
+ },
98
+
99
+ tracing: {
100
+ enabled: false,
101
+ // exporter: [
102
+ // "Console"
103
+ // ]
104
+ },
105
+
106
+ /**
107
+ * Transit options control the internal messaging layer of Moleculer
108
+ */
109
+ transit: {
110
+ maxQueueSize: 50 * 1000,
111
+ disableReconnect: false,
112
+ disableVersionCheck: false,
113
+ packetLogFilter: ["HEARTBEAT"]
114
+ },
115
+
116
+ uidGenerator: null,
117
+
118
+ errorHandler: null,
119
+
120
+ // cacher: "MemoryLRU",
121
+
122
+ /**
123
+ * Serializer
124
+ */
125
+ serializer: "MsgPack",
126
+
127
+ validator: true,
128
+ errorRegenerator: null,
129
+
130
+
131
+ internalServices: true,
132
+ internalMiddlewares: true,
133
+
134
+ hotReload: false,
135
+
136
+ // middlewares: ["MyMiddleware"],
137
+
138
+ replOptions: {
139
+ delimiter: "mol # ",
140
+ customCommands: [
141
+ {
142
+ command: "hello <name>",
143
+ action(broker, args) {
144
+ // ...
145
+ }
146
+ }
147
+ ]
148
+ },
149
+
150
+ metadata: {
151
+ // region: "eu-west1"
152
+ },
153
+
154
+ logger: "CustomPino",
155
+ logLevel: "error",
156
+
157
+ /**
158
+ * transporter configuration
159
+ */
160
+ transporter: {
161
+ type: "NATS",
162
+ options: {
163
+ /**
164
+ * High availability
165
+ */
166
+ servers: [
167
+ "nats://nats:nats123@nats:4222",
168
+ ],
169
+
170
+ user: "nats",
171
+ pass: "nats123",
172
+
173
+ /**
174
+ * Reconnect settings
175
+ */
176
+ reconnect: true,
177
+ maxReconnectAttempts: -1,
178
+ reconnectTimeWait: 2000,
179
+ waitOnFirstConnect: true,
180
+
181
+ /**
182
+ * Performance
183
+ */
184
+ maxInFlight: 1000,
185
+ timeout: 5000,
186
+
187
+ }
25
188
  }
26
- })
189
+ }
@@ -0,0 +1,5 @@
1
+ export default {
2
+ host: 'openobserve',
3
+ port: 5080,
4
+ token: "Basic cm9vdEBleGFtcGxlLmNvbTpQYll3S29vNDA0b3ZHWExJ"
5
+ }
@@ -113,7 +113,8 @@ const pkgService = readPkg(SERVICES_DIR)
113
113
  export const serviceDtls = {
114
114
  name: pkgService.name,
115
115
  version: pkgService.version,
116
- id: [pkgService.name, os.hostname(),process.pid].join("-")
116
+ id: [pkgService.name, os.hostname(), process.pid].join("-"),
117
+ osPid: [os.hostname(), process.pid].join("-")
117
118
  }
118
119
 
119
120