@fjell/registry 4.4.9 → 4.4.11

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/dist/Registry.cjs CHANGED
@@ -5,6 +5,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
5
5
  const logger$1 = require('./logger.cjs');
6
6
  const Instance = require('./Instance.cjs');
7
7
  const Coordinate = require('./Coordinate.cjs');
8
+ const RegistryStats = require('./RegistryStats.cjs');
8
9
 
9
10
  const logger = logger$1.default.get("Registry");
10
11
  const findScopedInstance = (scopedInstances, requestedScopes)=>{
@@ -29,13 +30,39 @@ const findScopedInstance = (scopedInstances, requestedScopes)=>{
29
30
  };
30
31
  const createRegistry = (type, registryHub)=>{
31
32
  const instanceTree = {};
33
+ // Statistics tracking
34
+ const registryStats = new RegistryStats.RegistryStats();
35
+ /**
36
+ * Creates a proxied Registry that automatically injects client information for service-to-service calls
37
+ */ const createProxiedRegistry = (callingCoordinate)=>{
38
+ const serviceClient = {
39
+ registryType: type,
40
+ coordinate: {
41
+ kta: callingCoordinate.kta,
42
+ scopes: callingCoordinate.scopes
43
+ }
44
+ };
45
+ return {
46
+ ...registry,
47
+ get: (kta, options)=>{
48
+ // Automatically inject the calling service as the client if no client is specified
49
+ const clientToUse = (options === null || options === void 0 ? void 0 : options.client) || serviceClient;
50
+ return registry.get(kta, {
51
+ ...options,
52
+ client: clientToUse
53
+ });
54
+ }
55
+ };
56
+ };
32
57
  const createInstance = (kta, scopes, factory)=>{
33
58
  logger.debug(`Creating and registering instance for key path and scopes`, kta, scopes, `in registry type: ${type}`);
34
59
  // Create coordinate for the instance
35
60
  const coordinate = Coordinate.createCoordinate(kta, scopes);
36
- // Use factory to create the instance with the new context parameter
61
+ // Create a proxied registry that automatically tracks this service as the client
62
+ const proxiedRegistry = createProxiedRegistry(coordinate);
63
+ // Use factory to create the instance with the proxied registry
37
64
  const instance = factory(coordinate, {
38
- registry,
65
+ registry: proxiedRegistry,
39
66
  registryHub
40
67
  });
41
68
  // Validate the created instance
@@ -87,6 +114,8 @@ const createRegistry = (type, registryHub)=>{
87
114
  registerInternal(kta, instance, options);
88
115
  };
89
116
  const get = (kta, options)=>{
117
+ // Track statistics with kta, scopes, and client
118
+ registryStats.recordGetCall(kta, options === null || options === void 0 ? void 0 : options.scopes, options === null || options === void 0 ? void 0 : options.client);
90
119
  const keyPath = [
91
120
  ...kta
92
121
  ].reverse();
@@ -133,6 +162,9 @@ const createRegistry = (type, registryHub)=>{
133
162
  traverseTree(instanceTree);
134
163
  return coordinates;
135
164
  };
165
+ const getStatistics = ()=>{
166
+ return registryStats.getStatistics();
167
+ };
136
168
  const registry = {
137
169
  type,
138
170
  registryHub,
@@ -140,10 +172,11 @@ const createRegistry = (type, registryHub)=>{
140
172
  register,
141
173
  get,
142
174
  getCoordinates,
175
+ getStatistics,
143
176
  instanceTree
144
177
  };
145
178
  return registry;
146
179
  };
147
180
 
148
181
  exports.createRegistry = createRegistry;
149
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUmVnaXN0cnkuY2pzIiwic291cmNlcyI6W10sInNvdXJjZXNDb250ZW50IjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7In0=
182
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUmVnaXN0cnkuY2pzIiwic291cmNlcyI6W10sInNvdXJjZXNDb250ZW50IjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7In0=
package/dist/Registry.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import LibLogger from './logger.js';
2
2
  import { isInstance } from './Instance.js';
3
3
  import { createCoordinate } from './Coordinate.js';
4
+ import { RegistryStats } from './RegistryStats.js';
4
5
 
5
6
  const logger = LibLogger.get("Registry");
6
7
  const findScopedInstance = (scopedInstances, requestedScopes)=>{
@@ -25,13 +26,39 @@ const findScopedInstance = (scopedInstances, requestedScopes)=>{
25
26
  };
26
27
  const createRegistry = (type, registryHub)=>{
27
28
  const instanceTree = {};
29
+ // Statistics tracking
30
+ const registryStats = new RegistryStats();
31
+ /**
32
+ * Creates a proxied Registry that automatically injects client information for service-to-service calls
33
+ */ const createProxiedRegistry = (callingCoordinate)=>{
34
+ const serviceClient = {
35
+ registryType: type,
36
+ coordinate: {
37
+ kta: callingCoordinate.kta,
38
+ scopes: callingCoordinate.scopes
39
+ }
40
+ };
41
+ return {
42
+ ...registry,
43
+ get: (kta, options)=>{
44
+ // Automatically inject the calling service as the client if no client is specified
45
+ const clientToUse = (options === null || options === void 0 ? void 0 : options.client) || serviceClient;
46
+ return registry.get(kta, {
47
+ ...options,
48
+ client: clientToUse
49
+ });
50
+ }
51
+ };
52
+ };
28
53
  const createInstance = (kta, scopes, factory)=>{
29
54
  logger.debug(`Creating and registering instance for key path and scopes`, kta, scopes, `in registry type: ${type}`);
30
55
  // Create coordinate for the instance
31
56
  const coordinate = createCoordinate(kta, scopes);
32
- // Use factory to create the instance with the new context parameter
57
+ // Create a proxied registry that automatically tracks this service as the client
58
+ const proxiedRegistry = createProxiedRegistry(coordinate);
59
+ // Use factory to create the instance with the proxied registry
33
60
  const instance = factory(coordinate, {
34
- registry,
61
+ registry: proxiedRegistry,
35
62
  registryHub
36
63
  });
37
64
  // Validate the created instance
@@ -83,6 +110,8 @@ const createRegistry = (type, registryHub)=>{
83
110
  registerInternal(kta, instance, options);
84
111
  };
85
112
  const get = (kta, options)=>{
113
+ // Track statistics with kta, scopes, and client
114
+ registryStats.recordGetCall(kta, options === null || options === void 0 ? void 0 : options.scopes, options === null || options === void 0 ? void 0 : options.client);
86
115
  const keyPath = [
87
116
  ...kta
88
117
  ].reverse();
@@ -129,6 +158,9 @@ const createRegistry = (type, registryHub)=>{
129
158
  traverseTree(instanceTree);
130
159
  return coordinates;
131
160
  };
161
+ const getStatistics = ()=>{
162
+ return registryStats.getStatistics();
163
+ };
132
164
  const registry = {
133
165
  type,
134
166
  registryHub,
@@ -136,10 +168,11 @@ const createRegistry = (type, registryHub)=>{
136
168
  register,
137
169
  get,
138
170
  getCoordinates,
171
+ getStatistics,
139
172
  instanceTree
140
173
  };
141
174
  return registry;
142
175
  };
143
176
 
144
177
  export { createRegistry };
145
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUmVnaXN0cnkuanMiLCJzb3VyY2VzIjpbXSwic291cmNlc0NvbnRlbnQiOltdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OyJ9
178
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUmVnaXN0cnkuanMiLCJzb3VyY2VzIjpbXSwic291cmNlc0NvbnRlbnQiOltdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OyJ9
@@ -0,0 +1,200 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
+
5
+ /**
6
+ * Represents a service client (another service making the request)
7
+ */ function _define_property(obj, key, value) {
8
+ if (key in obj) {
9
+ Object.defineProperty(obj, key, {
10
+ value: value,
11
+ enumerable: true,
12
+ configurable: true,
13
+ writable: true
14
+ });
15
+ } else {
16
+ obj[key] = value;
17
+ }
18
+ return obj;
19
+ }
20
+ /**
21
+ * Internal class for tracking Registry statistics with complex coordinate combinations and client tracking
22
+ */ class RegistryStats {
23
+ /**
24
+ * Records a get() call for the specified coordinate and client
25
+ */ recordGetCall(kta, scopes, client) {
26
+ this.totalCalls++;
27
+ const ktaKey = kta.join('.');
28
+ const scopeKey = this.createScopeKey(scopes || []);
29
+ const clientKey = this.createClientKey(client);
30
+ if (!this.coordinateCalls.has(ktaKey)) {
31
+ this.coordinateCalls.set(ktaKey, new Map());
32
+ }
33
+ const scopeMap = this.coordinateCalls.get(ktaKey);
34
+ if (!scopeMap.has(scopeKey)) {
35
+ scopeMap.set(scopeKey, new Map());
36
+ }
37
+ const clientMap = scopeMap.get(scopeKey);
38
+ const currentCount = clientMap.get(clientKey) || 0;
39
+ clientMap.set(clientKey, currentCount + 1);
40
+ }
41
+ /**
42
+ * Gets the current statistics snapshot
43
+ */ getStatistics() {
44
+ const coordinateCallRecords = [];
45
+ let serviceCalls = 0;
46
+ let applicationCalls = 0;
47
+ let unidentifiedCalls = 0;
48
+ for (const [ktaKey, scopeMap] of this.coordinateCalls){
49
+ for (const [scopeKey, clientMap] of scopeMap){
50
+ const clientCalls = [];
51
+ let totalCount = 0;
52
+ for (const [clientKey, count] of clientMap){
53
+ const client = this.parseClientKey(clientKey);
54
+ if (client !== null) {
55
+ clientCalls.push({
56
+ client,
57
+ count
58
+ });
59
+ }
60
+ totalCount += count;
61
+ // Update client summary
62
+ if (clientKey === '__no_client__') {
63
+ unidentifiedCalls += count;
64
+ } else if (typeof client === 'string') {
65
+ applicationCalls += count;
66
+ } else if (client !== null) {
67
+ serviceCalls += count;
68
+ }
69
+ }
70
+ coordinateCallRecords.push({
71
+ kta: ktaKey.split('.'),
72
+ scopes: this.parseScopeKey(scopeKey),
73
+ count: totalCount,
74
+ clientCalls: [
75
+ ...clientCalls
76
+ ] // Return a copy
77
+ });
78
+ }
79
+ }
80
+ return {
81
+ totalGetCalls: this.totalCalls,
82
+ coordinateCallRecords: [
83
+ ...coordinateCallRecords
84
+ ],
85
+ clientSummary: {
86
+ serviceCalls,
87
+ applicationCalls,
88
+ unidentifiedCalls
89
+ }
90
+ };
91
+ }
92
+ /**
93
+ * Gets call count for a specific coordinate combination
94
+ */ getCallCount(kta, scopes) {
95
+ const ktaKey = kta.join('.');
96
+ const scopeKey = this.createScopeKey(scopes || []);
97
+ const scopeMap = this.coordinateCalls.get(ktaKey);
98
+ if (!scopeMap) return 0;
99
+ const clientMap = scopeMap.get(scopeKey);
100
+ if (!clientMap) return 0;
101
+ let total = 0;
102
+ for (const count of clientMap.values()){
103
+ total += count;
104
+ }
105
+ return total;
106
+ }
107
+ /**
108
+ * Gets call count for a specific coordinate combination from a specific client
109
+ */ getCallCountByClient(kta, scopes, client) {
110
+ const ktaKey = kta.join('.');
111
+ const scopeKey = this.createScopeKey(scopes || []);
112
+ const clientKey = this.createClientKey(client);
113
+ const scopeMap = this.coordinateCalls.get(ktaKey);
114
+ if (!scopeMap) return 0;
115
+ const clientMap = scopeMap.get(scopeKey);
116
+ if (!clientMap) return 0;
117
+ return clientMap.get(clientKey) || 0;
118
+ }
119
+ /**
120
+ * Gets total calls for a specific kta (across all scopes)
121
+ */ getTotalCallsForKta(kta) {
122
+ const ktaKey = kta.join('.');
123
+ const scopeMap = this.coordinateCalls.get(ktaKey);
124
+ if (!scopeMap) return 0;
125
+ let total = 0;
126
+ for (const clientMap of scopeMap.values()){
127
+ for (const count of clientMap.values()){
128
+ total += count;
129
+ }
130
+ }
131
+ return total;
132
+ }
133
+ /**
134
+ * Gets all unique kta paths that have been called
135
+ */ getCalledKtaPaths() {
136
+ const ktaPaths = [];
137
+ for (const ktaKey of this.coordinateCalls.keys()){
138
+ ktaPaths.push(ktaKey.split('.'));
139
+ }
140
+ return ktaPaths;
141
+ }
142
+ /**
143
+ * Creates a normalized scope key from scopes array
144
+ */ createScopeKey(scopes) {
145
+ if (scopes.length === 0) return '__no_scopes__';
146
+ return [
147
+ ...scopes
148
+ ].sort().join(',');
149
+ }
150
+ /**
151
+ * Parses a scope key back to scopes array
152
+ */ parseScopeKey(scopeKey) {
153
+ if (scopeKey === '__no_scopes__') return [];
154
+ return scopeKey.split(',');
155
+ }
156
+ /**
157
+ * Creates a normalized client key from client identifier
158
+ */ createClientKey(client) {
159
+ if (!client) return '__no_client__';
160
+ if (typeof client === 'string') {
161
+ return `app:${client}`;
162
+ }
163
+ // Service client
164
+ const coordKey = `${client.coordinate.kta.join('.')};${this.createScopeKey(client.coordinate.scopes)}`;
165
+ return `service:${client.registryType}:${coordKey}`;
166
+ }
167
+ /**
168
+ * Parses a client key back to client identifier
169
+ */ parseClientKey(clientKey) {
170
+ if (clientKey === '__no_client__') return null;
171
+ if (clientKey.startsWith('app:')) {
172
+ return clientKey.substring(4);
173
+ }
174
+ if (clientKey.startsWith('service:')) {
175
+ const parts = clientKey.substring(8).split(':');
176
+ if (parts.length !== 2) return null;
177
+ const registryType = parts[0];
178
+ const coordParts = parts[1].split(';');
179
+ if (coordParts.length !== 2) return null;
180
+ const kta = coordParts[0].split('.');
181
+ const scopes = this.parseScopeKey(coordParts[1]);
182
+ return {
183
+ registryType,
184
+ coordinate: {
185
+ kta,
186
+ scopes
187
+ }
188
+ };
189
+ }
190
+ return null;
191
+ }
192
+ constructor(){
193
+ _define_property(this, "totalCalls", 0);
194
+ // Map structure: ktaKey -> scopeKey -> clientKey -> count
195
+ _define_property(this, "coordinateCalls", new Map());
196
+ }
197
+ }
198
+
199
+ exports.RegistryStats = RegistryStats;
200
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUmVnaXN0cnlTdGF0cy5janMiLCJzb3VyY2VzIjpbXSwic291cmNlc0NvbnRlbnQiOltdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsifQ==
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Represents a service client (another service making the request)
3
+ */
4
+ export interface ServiceClient {
5
+ /** The type of registry where the calling service is registered */
6
+ registryType: string;
7
+ /** The coordinate of the calling service */
8
+ coordinate: {
9
+ kta: string[];
10
+ scopes: string[];
11
+ };
12
+ }
13
+ /**
14
+ * Represents either a service or application client
15
+ */
16
+ export type ClientIdentifier = ServiceClient | string;
17
+ /**
18
+ * Represents a specific coordinate call with both kta and scopes
19
+ */
20
+ export interface CoordinateCallRecord {
21
+ /** The key type array that was requested */
22
+ kta: string[];
23
+ /** The scopes that were requested (empty array if no scopes) */
24
+ scopes: string[];
25
+ /** Number of times this exact combination was called */
26
+ count: number;
27
+ /** Breakdown of calls by client */
28
+ clientCalls: ClientCallRecord[];
29
+ }
30
+ /**
31
+ * Represents calls from a specific client
32
+ */
33
+ export interface ClientCallRecord {
34
+ /** The client that made the calls */
35
+ client: ClientIdentifier;
36
+ /** Number of calls from this client */
37
+ count: number;
38
+ }
39
+ /**
40
+ * Statistics about Registry get() method calls with detailed coordinate tracking
41
+ */
42
+ export interface RegistryStatistics {
43
+ /** Total number of get() calls made on this registry */
44
+ totalGetCalls: number;
45
+ /** Detailed records of each unique coordinate combination and their call counts */
46
+ coordinateCallRecords: CoordinateCallRecord[];
47
+ /** Summary of calls by client type */
48
+ clientSummary: {
49
+ /** Total calls from services (service-to-service) */
50
+ serviceCalls: number;
51
+ /** Total calls from applications (direct application calls) */
52
+ applicationCalls: number;
53
+ /** Total calls with no client specified */
54
+ unidentifiedCalls: number;
55
+ };
56
+ }
57
+ /**
58
+ * Internal class for tracking Registry statistics with complex coordinate combinations and client tracking
59
+ */
60
+ export declare class RegistryStats {
61
+ private totalCalls;
62
+ private coordinateCalls;
63
+ /**
64
+ * Records a get() call for the specified coordinate and client
65
+ */
66
+ recordGetCall(kta: string[], scopes?: string[], client?: ClientIdentifier): void;
67
+ /**
68
+ * Gets the current statistics snapshot
69
+ */
70
+ getStatistics(): RegistryStatistics;
71
+ /**
72
+ * Gets call count for a specific coordinate combination
73
+ */
74
+ getCallCount(kta: string[], scopes?: string[]): number;
75
+ /**
76
+ * Gets call count for a specific coordinate combination from a specific client
77
+ */
78
+ getCallCountByClient(kta: string[], scopes?: string[], client?: ClientIdentifier): number;
79
+ /**
80
+ * Gets total calls for a specific kta (across all scopes)
81
+ */
82
+ getTotalCallsForKta(kta: string[]): number;
83
+ /**
84
+ * Gets all unique kta paths that have been called
85
+ */
86
+ getCalledKtaPaths(): string[][];
87
+ /**
88
+ * Creates a normalized scope key from scopes array
89
+ */
90
+ private createScopeKey;
91
+ /**
92
+ * Parses a scope key back to scopes array
93
+ */
94
+ private parseScopeKey;
95
+ /**
96
+ * Creates a normalized client key from client identifier
97
+ */
98
+ private createClientKey;
99
+ /**
100
+ * Parses a client key back to client identifier
101
+ */
102
+ private parseClientKey;
103
+ }
@@ -0,0 +1,196 @@
1
+ /**
2
+ * Represents a service client (another service making the request)
3
+ */ function _define_property(obj, key, value) {
4
+ if (key in obj) {
5
+ Object.defineProperty(obj, key, {
6
+ value: value,
7
+ enumerable: true,
8
+ configurable: true,
9
+ writable: true
10
+ });
11
+ } else {
12
+ obj[key] = value;
13
+ }
14
+ return obj;
15
+ }
16
+ /**
17
+ * Internal class for tracking Registry statistics with complex coordinate combinations and client tracking
18
+ */ class RegistryStats {
19
+ /**
20
+ * Records a get() call for the specified coordinate and client
21
+ */ recordGetCall(kta, scopes, client) {
22
+ this.totalCalls++;
23
+ const ktaKey = kta.join('.');
24
+ const scopeKey = this.createScopeKey(scopes || []);
25
+ const clientKey = this.createClientKey(client);
26
+ if (!this.coordinateCalls.has(ktaKey)) {
27
+ this.coordinateCalls.set(ktaKey, new Map());
28
+ }
29
+ const scopeMap = this.coordinateCalls.get(ktaKey);
30
+ if (!scopeMap.has(scopeKey)) {
31
+ scopeMap.set(scopeKey, new Map());
32
+ }
33
+ const clientMap = scopeMap.get(scopeKey);
34
+ const currentCount = clientMap.get(clientKey) || 0;
35
+ clientMap.set(clientKey, currentCount + 1);
36
+ }
37
+ /**
38
+ * Gets the current statistics snapshot
39
+ */ getStatistics() {
40
+ const coordinateCallRecords = [];
41
+ let serviceCalls = 0;
42
+ let applicationCalls = 0;
43
+ let unidentifiedCalls = 0;
44
+ for (const [ktaKey, scopeMap] of this.coordinateCalls){
45
+ for (const [scopeKey, clientMap] of scopeMap){
46
+ const clientCalls = [];
47
+ let totalCount = 0;
48
+ for (const [clientKey, count] of clientMap){
49
+ const client = this.parseClientKey(clientKey);
50
+ if (client !== null) {
51
+ clientCalls.push({
52
+ client,
53
+ count
54
+ });
55
+ }
56
+ totalCount += count;
57
+ // Update client summary
58
+ if (clientKey === '__no_client__') {
59
+ unidentifiedCalls += count;
60
+ } else if (typeof client === 'string') {
61
+ applicationCalls += count;
62
+ } else if (client !== null) {
63
+ serviceCalls += count;
64
+ }
65
+ }
66
+ coordinateCallRecords.push({
67
+ kta: ktaKey.split('.'),
68
+ scopes: this.parseScopeKey(scopeKey),
69
+ count: totalCount,
70
+ clientCalls: [
71
+ ...clientCalls
72
+ ] // Return a copy
73
+ });
74
+ }
75
+ }
76
+ return {
77
+ totalGetCalls: this.totalCalls,
78
+ coordinateCallRecords: [
79
+ ...coordinateCallRecords
80
+ ],
81
+ clientSummary: {
82
+ serviceCalls,
83
+ applicationCalls,
84
+ unidentifiedCalls
85
+ }
86
+ };
87
+ }
88
+ /**
89
+ * Gets call count for a specific coordinate combination
90
+ */ getCallCount(kta, scopes) {
91
+ const ktaKey = kta.join('.');
92
+ const scopeKey = this.createScopeKey(scopes || []);
93
+ const scopeMap = this.coordinateCalls.get(ktaKey);
94
+ if (!scopeMap) return 0;
95
+ const clientMap = scopeMap.get(scopeKey);
96
+ if (!clientMap) return 0;
97
+ let total = 0;
98
+ for (const count of clientMap.values()){
99
+ total += count;
100
+ }
101
+ return total;
102
+ }
103
+ /**
104
+ * Gets call count for a specific coordinate combination from a specific client
105
+ */ getCallCountByClient(kta, scopes, client) {
106
+ const ktaKey = kta.join('.');
107
+ const scopeKey = this.createScopeKey(scopes || []);
108
+ const clientKey = this.createClientKey(client);
109
+ const scopeMap = this.coordinateCalls.get(ktaKey);
110
+ if (!scopeMap) return 0;
111
+ const clientMap = scopeMap.get(scopeKey);
112
+ if (!clientMap) return 0;
113
+ return clientMap.get(clientKey) || 0;
114
+ }
115
+ /**
116
+ * Gets total calls for a specific kta (across all scopes)
117
+ */ getTotalCallsForKta(kta) {
118
+ const ktaKey = kta.join('.');
119
+ const scopeMap = this.coordinateCalls.get(ktaKey);
120
+ if (!scopeMap) return 0;
121
+ let total = 0;
122
+ for (const clientMap of scopeMap.values()){
123
+ for (const count of clientMap.values()){
124
+ total += count;
125
+ }
126
+ }
127
+ return total;
128
+ }
129
+ /**
130
+ * Gets all unique kta paths that have been called
131
+ */ getCalledKtaPaths() {
132
+ const ktaPaths = [];
133
+ for (const ktaKey of this.coordinateCalls.keys()){
134
+ ktaPaths.push(ktaKey.split('.'));
135
+ }
136
+ return ktaPaths;
137
+ }
138
+ /**
139
+ * Creates a normalized scope key from scopes array
140
+ */ createScopeKey(scopes) {
141
+ if (scopes.length === 0) return '__no_scopes__';
142
+ return [
143
+ ...scopes
144
+ ].sort().join(',');
145
+ }
146
+ /**
147
+ * Parses a scope key back to scopes array
148
+ */ parseScopeKey(scopeKey) {
149
+ if (scopeKey === '__no_scopes__') return [];
150
+ return scopeKey.split(',');
151
+ }
152
+ /**
153
+ * Creates a normalized client key from client identifier
154
+ */ createClientKey(client) {
155
+ if (!client) return '__no_client__';
156
+ if (typeof client === 'string') {
157
+ return `app:${client}`;
158
+ }
159
+ // Service client
160
+ const coordKey = `${client.coordinate.kta.join('.')};${this.createScopeKey(client.coordinate.scopes)}`;
161
+ return `service:${client.registryType}:${coordKey}`;
162
+ }
163
+ /**
164
+ * Parses a client key back to client identifier
165
+ */ parseClientKey(clientKey) {
166
+ if (clientKey === '__no_client__') return null;
167
+ if (clientKey.startsWith('app:')) {
168
+ return clientKey.substring(4);
169
+ }
170
+ if (clientKey.startsWith('service:')) {
171
+ const parts = clientKey.substring(8).split(':');
172
+ if (parts.length !== 2) return null;
173
+ const registryType = parts[0];
174
+ const coordParts = parts[1].split(';');
175
+ if (coordParts.length !== 2) return null;
176
+ const kta = coordParts[0].split('.');
177
+ const scopes = this.parseScopeKey(coordParts[1]);
178
+ return {
179
+ registryType,
180
+ coordinate: {
181
+ kta,
182
+ scopes
183
+ }
184
+ };
185
+ }
186
+ return null;
187
+ }
188
+ constructor(){
189
+ _define_property(this, "totalCalls", 0);
190
+ // Map structure: ktaKey -> scopeKey -> clientKey -> count
191
+ _define_property(this, "coordinateCalls", new Map());
192
+ }
193
+ }
194
+
195
+ export { RegistryStats };
196
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUmVnaXN0cnlTdGF0cy5qcyIsInNvdXJjZXMiOltdLCJzb3VyY2VzQ29udGVudCI6W10sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7In0=