@onlineapps/service-wrapper 2.2.6 → 2.2.8

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/jest.config.js CHANGED
@@ -27,7 +27,8 @@ module.exports = {
27
27
  '@onlineapps/conn-base-logger': '<rootDir>/tests/mocks/connectors.js',
28
28
  '@onlineapps/conn-orch-orchestrator': '<rootDir>/tests/mocks/connectors.js',
29
29
  '@onlineapps/conn-orch-api-mapper': '<rootDir>/tests/mocks/connectors.js',
30
- '@onlineapps/conn-orch-cookbook': '<rootDir>/tests/mocks/connectors.js'
30
+ '@onlineapps/conn-orch-cookbook': '<rootDir>/tests/mocks/connectors.js',
31
+ '@onlineapps/conn-base-state': '<rootDir>/tests/mocks/connectors.js'
31
32
  },
32
33
  setupFilesAfterEnv: ['<rootDir>/tests/setup.js'],
33
34
  verbose: true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onlineapps/service-wrapper",
3
- "version": "2.2.6",
3
+ "version": "2.2.8",
4
4
  "description": "Thin orchestration layer for microservices - delegates all infrastructure concerns to specialized connectors",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -24,7 +24,8 @@
24
24
  "author": "OA Drive Team",
25
25
  "license": "MIT",
26
26
  "dependencies": {
27
- "@onlineapps/conn-base-cache": "1.0.8",
27
+ "@onlineapps/conn-base-cache": "1.0.9",
28
+ "@onlineapps/conn-base-state": "1.0.1",
28
29
  "@onlineapps/conn-base-monitoring": "1.0.10",
29
30
  "@onlineapps/conn-infra-error-handler": "1.0.9",
30
31
  "@onlineapps/conn-infra-mq": "1.1.69",
@@ -34,7 +35,7 @@
34
35
  "@onlineapps/conn-orch-registry": "1.1.54",
35
36
  "@onlineapps/conn-orch-validator": "2.0.31",
36
37
  "@onlineapps/monitoring-core": "1.0.21",
37
- "@onlineapps/service-common": "1.0.17",
38
+ "@onlineapps/service-common": "1.0.18",
38
39
  "@onlineapps/runtime-config": "1.0.2"
39
40
  },
40
41
  "devDependencies": {
@@ -20,6 +20,7 @@ const OrchestratorConnector = require('@onlineapps/conn-orch-orchestrator');
20
20
  const ApiMapperConnector = require('@onlineapps/conn-orch-api-mapper');
21
21
  const CookbookConnector = require('@onlineapps/conn-orch-cookbook');
22
22
  const CacheConnector = require('@onlineapps/conn-base-cache');
23
+ const StateConnector = require('@onlineapps/conn-base-state');
23
24
  const ErrorHandlerConnector = require('@onlineapps/conn-infra-error-handler');
24
25
  const { ValidationOrchestrator } = require('@onlineapps/conn-orch-validator');
25
26
  const runtimeCfg = require('./config');
@@ -415,13 +416,22 @@ class ServiceWrapper {
415
416
  }
416
417
  }
417
418
 
418
- // 4. Close Redis connection (if used)
419
+ // 4. Close Redis connections (cache + state)
419
420
  if (this.cacheConnector) {
420
421
  try {
421
422
  await this.cacheConnector.disconnect();
422
- console.log(`[CLEANUP] ✓ Closed Redis connection`);
423
+ console.log(`[CLEANUP] ✓ Closed Redis cache connection`);
423
424
  } catch (err) {
424
- console.warn(`[CLEANUP] Failed to close Redis connection:`, err.message);
425
+ console.warn(`[CLEANUP] Failed to close Redis cache connection:`, err.message);
426
+ }
427
+ }
428
+
429
+ if (this.stateConnector) {
430
+ try {
431
+ await this.stateConnector.disconnect();
432
+ console.log(`[CLEANUP] ✓ Closed Redis state connection`);
433
+ } catch (err) {
434
+ console.warn(`[CLEANUP] Failed to close Redis state connection:`, err.message);
425
435
  }
426
436
  }
427
437
 
@@ -574,6 +584,11 @@ class ServiceWrapper {
574
584
  }
575
585
  }
576
586
 
587
+ // Initialize state connector if configured (critical — let it throw)
588
+ if (this.config.wrapper?.state?.enabled === true) {
589
+ await this._initializeState();
590
+ }
591
+
577
592
  // Setup health checks
578
593
  if (this.config.wrapper?.health?.enabled !== false) {
579
594
  this._setupHealthChecks();
@@ -1070,8 +1085,17 @@ class ServiceWrapper {
1070
1085
 
1071
1086
  const serviceName = this.config.service?.name || 'unnamed-service';
1072
1087
 
1088
+ let host = cacheUrl;
1089
+ let port = 6379;
1090
+ if (cacheUrl.startsWith('redis://')) {
1091
+ const parsed = new URL(cacheUrl);
1092
+ host = parsed.hostname;
1093
+ port = parseInt(parsed.port, 10) || 6379;
1094
+ }
1095
+
1073
1096
  this.cacheConnector = new CacheConnector({
1074
- host: cacheUrl,
1097
+ host,
1098
+ port,
1075
1099
  namespace: serviceName,
1076
1100
  defaultTTL: this.config.wrapper?.cache?.ttl || 300
1077
1101
  });
@@ -1080,6 +1104,37 @@ class ServiceWrapper {
1080
1104
  this.logger?.info('Cache connector initialized');
1081
1105
  }
1082
1106
 
1107
+ /**
1108
+ * Initialize state connector (persistent Redis state, no TTL)
1109
+ * @private
1110
+ */
1111
+ async _initializeState() {
1112
+ const stateConfig = this.config.wrapper?.state;
1113
+ const serviceName = stateConfig?.serviceName || this.config.service?.name;
1114
+ if (!serviceName) {
1115
+ throw new Error('[ServiceWrapper] state.serviceName or service.name is required when state is enabled');
1116
+ }
1117
+
1118
+ const cacheUrl = this.config.wrapper?.cache?.url;
1119
+ let host, port;
1120
+ if (cacheUrl?.startsWith('redis://')) {
1121
+ const parsed = new URL(cacheUrl);
1122
+ host = parsed.hostname;
1123
+ port = parseInt(parsed.port, 10);
1124
+ }
1125
+
1126
+ this.stateConnector = new StateConnector({
1127
+ host: stateConfig?.host || host,
1128
+ port: stateConfig?.port || port,
1129
+ password: stateConfig?.password,
1130
+ db: stateConfig?.db,
1131
+ serviceName,
1132
+ });
1133
+
1134
+ await this.stateConnector.connect();
1135
+ this.logger?.info('State connector initialized');
1136
+ }
1137
+
1083
1138
  /**
1084
1139
  * Setup health check endpoint
1085
1140
  * @private
@@ -1096,7 +1151,8 @@ class ServiceWrapper {
1096
1151
  http: 'healthy',
1097
1152
  mq: 'disabled',
1098
1153
  registry: this.registryClient ? 'healthy' : 'disabled',
1099
- cache: this.cacheConnector ? 'healthy' : 'disabled'
1154
+ cache: this.cacheConnector ? 'healthy' : 'disabled',
1155
+ state: this.stateConnector ? 'healthy' : 'disabled'
1100
1156
  }
1101
1157
  };
1102
1158
 
@@ -2052,6 +2108,11 @@ class ServiceWrapper {
2052
2108
  await this.cacheConnector.disconnect();
2053
2109
  }
2054
2110
 
2111
+ // Disconnect from state
2112
+ if (this.stateConnector) {
2113
+ await this.stateConnector.disconnect();
2114
+ }
2115
+
2055
2116
  // Disconnect from MQ
2056
2117
  if (this.mqClient) {
2057
2118
  await this.mqClient.disconnect();