@kadi.build/core 0.0.1-alpha.1 → 0.0.1-alpha.10
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 +1387 -214
- package/dist/abilities/AbilityCache.d.ts +242 -0
- package/dist/abilities/AbilityCache.d.ts.map +1 -0
- package/dist/abilities/AbilityCache.js +285 -0
- package/dist/abilities/AbilityCache.js.map +1 -0
- package/dist/abilities/AbilityContext.d.ts +215 -0
- package/dist/abilities/AbilityContext.d.ts.map +1 -0
- package/dist/abilities/AbilityContext.js +36 -0
- package/dist/abilities/AbilityContext.js.map +1 -0
- package/dist/abilities/AbilityLoader.d.ts +177 -0
- package/dist/abilities/AbilityLoader.d.ts.map +1 -0
- package/dist/abilities/AbilityLoader.js +277 -0
- package/dist/abilities/AbilityLoader.js.map +1 -0
- package/dist/abilities/AbilityProxy.d.ts +463 -0
- package/dist/abilities/AbilityProxy.d.ts.map +1 -0
- package/dist/abilities/AbilityProxy.js +511 -0
- package/dist/abilities/AbilityProxy.js.map +1 -0
- package/dist/abilities/AbilityValidator.d.ts +172 -0
- package/dist/abilities/AbilityValidator.d.ts.map +1 -0
- package/dist/abilities/AbilityValidator.js +253 -0
- package/dist/abilities/AbilityValidator.js.map +1 -0
- package/dist/abilities/index.d.ts +26 -0
- package/dist/abilities/index.d.ts.map +1 -0
- package/dist/abilities/index.js +23 -0
- package/dist/abilities/index.js.map +1 -0
- package/dist/abilities/types.d.ts +156 -0
- package/dist/abilities/types.d.ts.map +1 -0
- package/dist/abilities/types.js +10 -0
- package/dist/abilities/types.js.map +1 -0
- package/dist/api/index.d.ts +92 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +124 -0
- package/dist/api/index.js.map +1 -0
- package/dist/broker/BrokerConnection.d.ts +253 -0
- package/dist/broker/BrokerConnection.d.ts.map +1 -0
- package/dist/broker/BrokerConnection.js +434 -0
- package/dist/broker/BrokerConnection.js.map +1 -0
- package/dist/broker/BrokerConnectionManager.d.ts +216 -0
- package/dist/broker/BrokerConnectionManager.d.ts.map +1 -0
- package/dist/broker/BrokerConnectionManager.js +305 -0
- package/dist/broker/BrokerConnectionManager.js.map +1 -0
- package/dist/broker/BrokerProtocol.d.ts +280 -0
- package/dist/broker/BrokerProtocol.d.ts.map +1 -0
- package/dist/broker/BrokerProtocol.js +466 -0
- package/dist/broker/BrokerProtocol.js.map +1 -0
- package/dist/broker/index.d.ts +9 -0
- package/dist/broker/index.d.ts.map +1 -0
- package/dist/broker/index.js +9 -0
- package/dist/broker/index.js.map +1 -0
- package/dist/client/KadiClient.d.ts +270 -0
- package/dist/client/KadiClient.d.ts.map +1 -0
- package/dist/client/KadiClient.js +492 -0
- package/dist/client/KadiClient.js.map +1 -0
- package/dist/client/index.d.ts +7 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +7 -0
- package/dist/client/index.js.map +1 -0
- package/dist/config/ConfigLoader.d.ts +138 -0
- package/dist/config/ConfigLoader.d.ts.map +1 -0
- package/dist/config/ConfigLoader.js +226 -0
- package/dist/config/ConfigLoader.js.map +1 -0
- package/dist/config/ConfigResolver.d.ts +135 -0
- package/dist/config/ConfigResolver.d.ts.map +1 -0
- package/dist/config/ConfigResolver.js +282 -0
- package/dist/config/ConfigResolver.js.map +1 -0
- package/dist/config/index.d.ts +8 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +8 -0
- package/dist/config/index.js.map +1 -0
- package/dist/errors/index.d.ts +9 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +8 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/events/EventHub.d.ts +172 -0
- package/dist/events/EventHub.d.ts.map +1 -0
- package/dist/events/EventHub.js +333 -0
- package/dist/events/EventHub.js.map +1 -0
- package/dist/events/index.d.ts +7 -0
- package/dist/events/index.d.ts.map +1 -0
- package/dist/events/index.js +7 -0
- package/dist/events/index.js.map +1 -0
- package/dist/index.d.ts +49 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +63 -0
- package/dist/index.js.map +1 -0
- package/dist/messages/index.d.ts +33 -0
- package/dist/messages/index.d.ts.map +1 -0
- package/dist/messages/index.js +33 -0
- package/dist/messages/index.js.map +1 -0
- package/dist/schemas/index.d.ts +19 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +25 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/kadi-extensions.d.ts +231 -0
- package/dist/schemas/kadi-extensions.d.ts.map +1 -0
- package/dist/schemas/kadi-extensions.js +14 -0
- package/dist/schemas/kadi-extensions.js.map +1 -0
- package/dist/schemas/mcp/schema.d.ts +1399 -0
- package/dist/schemas/mcp/schema.d.ts.map +1 -0
- package/dist/schemas/mcp/schema.js +53 -0
- package/dist/schemas/mcp/schema.js.map +1 -0
- package/dist/schemas/mcp/version.d.ts +37 -0
- package/dist/schemas/mcp/version.d.ts.map +1 -0
- package/dist/schemas/mcp/version.js +39 -0
- package/dist/schemas/mcp/version.js.map +1 -0
- package/dist/schemas/schema-builders.d.ts +178 -0
- package/dist/schemas/schema-builders.d.ts.map +1 -0
- package/dist/schemas/schema-builders.js +258 -0
- package/dist/schemas/schema-builders.js.map +1 -0
- package/dist/tools/ToolRegistry.d.ts +256 -0
- package/dist/tools/ToolRegistry.d.ts.map +1 -0
- package/dist/tools/ToolRegistry.js +340 -0
- package/dist/tools/ToolRegistry.js.map +1 -0
- package/dist/tools/index.d.ts +7 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +7 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/transports/BrokerTransport.d.ts +151 -0
- package/dist/transports/BrokerTransport.d.ts.map +1 -0
- package/dist/transports/BrokerTransport.js +261 -0
- package/dist/transports/BrokerTransport.js.map +1 -0
- package/dist/transports/NativeTransport.d.ts +149 -0
- package/dist/transports/NativeTransport.d.ts.map +1 -0
- package/dist/transports/NativeTransport.js +302 -0
- package/dist/transports/NativeTransport.js.map +1 -0
- package/dist/transports/StdioTransport.d.ts +172 -0
- package/dist/transports/StdioTransport.d.ts.map +1 -0
- package/dist/transports/StdioTransport.js +410 -0
- package/dist/transports/StdioTransport.js.map +1 -0
- package/dist/transports/index.d.ts +10 -0
- package/dist/transports/index.d.ts.map +1 -0
- package/dist/transports/index.js +9 -0
- package/dist/transports/index.js.map +1 -0
- package/dist/types/broker.d.ts +301 -0
- package/dist/types/broker.d.ts.map +1 -0
- package/dist/types/broker.js +46 -0
- package/dist/types/broker.js.map +1 -0
- package/dist/types/config.d.ts +325 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +17 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/errors.d.ts +178 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/errors.js +165 -0
- package/dist/types/errors.js.map +1 -0
- package/dist/types/events.d.ts +210 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/events.js +8 -0
- package/dist/types/events.js.map +1 -0
- package/dist/types/index.d.ts +32 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +21 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/protocol.d.ts +48 -0
- package/dist/types/protocol.d.ts.map +1 -0
- package/dist/types/protocol.js +11 -0
- package/dist/types/protocol.js.map +1 -0
- package/dist/types/tools.d.ts +67 -0
- package/dist/types/tools.d.ts.map +1 -0
- package/dist/types/tools.js +16 -0
- package/dist/types/tools.js.map +1 -0
- package/dist/types/transport.d.ts +250 -0
- package/dist/types/transport.d.ts.map +1 -0
- package/dist/types/transport.js +18 -0
- package/dist/types/transport.js.map +1 -0
- package/dist/validation/SchemaValidator.d.ts +208 -0
- package/dist/validation/SchemaValidator.d.ts.map +1 -0
- package/dist/validation/SchemaValidator.js +411 -0
- package/dist/validation/SchemaValidator.js.map +1 -0
- package/dist/validation/index.d.ts +11 -0
- package/dist/validation/index.d.ts.map +1 -0
- package/dist/validation/index.js +10 -0
- package/dist/validation/index.js.map +1 -0
- package/package.json +69 -5
- package/agent.json +0 -18
- package/broker.js +0 -214
- package/index.js +0 -370
- package/ipc.js +0 -220
- package/ipcInterfaces/pythonAbilityIPC.py +0 -177
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ability Cache
|
|
3
|
+
*
|
|
4
|
+
* Smart caching with composite keys to handle complex scenarios:
|
|
5
|
+
* - Same ability name, different transports
|
|
6
|
+
* - Same ability name, different versions
|
|
7
|
+
* - Same ability name, different brokers
|
|
8
|
+
*
|
|
9
|
+
* @module abilities/AbilityCache
|
|
10
|
+
*/
|
|
11
|
+
import type { LoadedAbility } from './AbilityProxy.js';
|
|
12
|
+
import type { TransportType } from './types.js';
|
|
13
|
+
/**
|
|
14
|
+
* Cache key components
|
|
15
|
+
*
|
|
16
|
+
* All factors that make an ability unique in the cache.
|
|
17
|
+
* Two abilities are considered "same" only if ALL components match.
|
|
18
|
+
*/
|
|
19
|
+
export interface CacheKey {
|
|
20
|
+
/**
|
|
21
|
+
* Ability name
|
|
22
|
+
*/
|
|
23
|
+
name: string;
|
|
24
|
+
/**
|
|
25
|
+
* Transport type used to load it
|
|
26
|
+
*
|
|
27
|
+
* Same ability via broker vs native are cached separately.
|
|
28
|
+
*/
|
|
29
|
+
transport: TransportType;
|
|
30
|
+
/**
|
|
31
|
+
* Version constraint (optional)
|
|
32
|
+
*
|
|
33
|
+
* Same ability, different versions are cached separately.
|
|
34
|
+
*/
|
|
35
|
+
version?: string;
|
|
36
|
+
/**
|
|
37
|
+
* Broker name (optional)
|
|
38
|
+
*
|
|
39
|
+
* Same ability from different brokers cached separately.
|
|
40
|
+
* Only relevant for broker transport.
|
|
41
|
+
*/
|
|
42
|
+
broker?: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Ability Cache
|
|
46
|
+
*
|
|
47
|
+
* Intelligent caching that avoids loading same ability multiple times,
|
|
48
|
+
* while correctly handling scenarios where same name ≠ same ability.
|
|
49
|
+
*
|
|
50
|
+
* **Why Composite Keys?**
|
|
51
|
+
*
|
|
52
|
+
* Consider:
|
|
53
|
+
* ```typescript
|
|
54
|
+
* const local = await client.load('calc', { transport: 'native' });
|
|
55
|
+
* const remote = await client.load('calc', { transport: 'broker' });
|
|
56
|
+
* ```
|
|
57
|
+
*
|
|
58
|
+
* These are DIFFERENT abilities (different implementations, different transports)
|
|
59
|
+
* despite having same name. Cache must treat them separately!
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```typescript
|
|
63
|
+
* const cache = new AbilityCache();
|
|
64
|
+
*
|
|
65
|
+
* // Store ability
|
|
66
|
+
* cache.set({ name: 'calc', transport: 'broker' }, ability);
|
|
67
|
+
*
|
|
68
|
+
* // Retrieve ability
|
|
69
|
+
* const cached = cache.get({ name: 'calc', transport: 'broker' });
|
|
70
|
+
*
|
|
71
|
+
* // Different transport = different cache entry
|
|
72
|
+
* const notFound = cache.get({ name: 'calc', transport: 'native' });
|
|
73
|
+
* // Returns undefined (different transport)
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
export declare class AbilityCache {
|
|
77
|
+
/**
|
|
78
|
+
* Internal cache storage
|
|
79
|
+
*
|
|
80
|
+
* Key: composite string (name:transport:version:broker)
|
|
81
|
+
* Value: loaded ability instance
|
|
82
|
+
*/
|
|
83
|
+
private cache;
|
|
84
|
+
/**
|
|
85
|
+
* Generate composite cache key from components
|
|
86
|
+
*
|
|
87
|
+
* Format: `name:transport[:version][:broker]`
|
|
88
|
+
*
|
|
89
|
+
* Optional components only included if present:
|
|
90
|
+
* - Basic: "calculator:broker"
|
|
91
|
+
* - With version: "calculator:broker:2.0.0"
|
|
92
|
+
* - With broker: "calculator:broker::main-broker"
|
|
93
|
+
* - Full: "calculator:broker:2.0.0:main-broker"
|
|
94
|
+
*
|
|
95
|
+
* @param key - Cache key components
|
|
96
|
+
* @returns Composite key string
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* ```typescript
|
|
100
|
+
* generateKey({ name: 'calc', transport: 'broker' })
|
|
101
|
+
* // Returns: "calc:broker"
|
|
102
|
+
*
|
|
103
|
+
* generateKey({ name: 'calc', transport: 'broker', version: '2.0.0' })
|
|
104
|
+
* // Returns: "calc:broker:2.0.0"
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
private generateKey;
|
|
108
|
+
/**
|
|
109
|
+
* Get cached ability
|
|
110
|
+
*
|
|
111
|
+
* Returns cached instance if exists and still connected.
|
|
112
|
+
* Returns undefined if not cached or disconnected.
|
|
113
|
+
*
|
|
114
|
+
* @param key - Cache key components
|
|
115
|
+
* @returns Cached ability or undefined
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```typescript
|
|
119
|
+
* const ability = cache.get({
|
|
120
|
+
* name: 'calculator',
|
|
121
|
+
* transport: 'broker'
|
|
122
|
+
* });
|
|
123
|
+
*
|
|
124
|
+
* if (ability) {
|
|
125
|
+
* // Cache hit! Use cached ability
|
|
126
|
+
* await ability.add({ a: 5, b: 3 });
|
|
127
|
+
* } else {
|
|
128
|
+
* // Cache miss - need to load
|
|
129
|
+
* }
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
132
|
+
get(key: CacheKey): LoadedAbility | undefined;
|
|
133
|
+
/**
|
|
134
|
+
* Store ability in cache
|
|
135
|
+
*
|
|
136
|
+
* Overwrites existing entry if present.
|
|
137
|
+
*
|
|
138
|
+
* @param key - Cache key components
|
|
139
|
+
* @param ability - Loaded ability to cache
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* ```typescript
|
|
143
|
+
* cache.set(
|
|
144
|
+
* { name: 'calculator', transport: 'broker', version: '2.0.0' },
|
|
145
|
+
* loadedAbility
|
|
146
|
+
* );
|
|
147
|
+
* ```
|
|
148
|
+
*/
|
|
149
|
+
set(key: CacheKey, ability: LoadedAbility): void;
|
|
150
|
+
/**
|
|
151
|
+
* Check if ability exists in cache
|
|
152
|
+
*
|
|
153
|
+
* Returns true only if cached AND still connected.
|
|
154
|
+
*
|
|
155
|
+
* @param key - Cache key components
|
|
156
|
+
* @returns true if cached and connected
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* ```typescript
|
|
160
|
+
* if (cache.has({ name: 'calc', transport: 'broker' })) {
|
|
161
|
+
* // Can safely use cached version
|
|
162
|
+
* }
|
|
163
|
+
* ```
|
|
164
|
+
*/
|
|
165
|
+
has(key: CacheKey): boolean;
|
|
166
|
+
/**
|
|
167
|
+
* Remove ability from cache
|
|
168
|
+
*
|
|
169
|
+
* @param key - Cache key components
|
|
170
|
+
* @returns true if was cached (now removed), false if wasn't cached
|
|
171
|
+
*
|
|
172
|
+
* @example
|
|
173
|
+
* ```typescript
|
|
174
|
+
* cache.delete({ name: 'calc', transport: 'broker' });
|
|
175
|
+
* ```
|
|
176
|
+
*/
|
|
177
|
+
delete(key: CacheKey): boolean;
|
|
178
|
+
/**
|
|
179
|
+
* Clear all cached abilities
|
|
180
|
+
*
|
|
181
|
+
* Removes everything from cache.
|
|
182
|
+
* Usually called during client disconnect/cleanup.
|
|
183
|
+
*
|
|
184
|
+
* @example
|
|
185
|
+
* ```typescript
|
|
186
|
+
* cache.clear();
|
|
187
|
+
* ```
|
|
188
|
+
*/
|
|
189
|
+
clear(): void;
|
|
190
|
+
/**
|
|
191
|
+
* Get all cached abilities
|
|
192
|
+
*
|
|
193
|
+
* Returns array of all cached ability instances.
|
|
194
|
+
* Useful for bulk operations like disconnect.
|
|
195
|
+
*
|
|
196
|
+
* @returns Array of loaded abilities
|
|
197
|
+
*
|
|
198
|
+
* @example
|
|
199
|
+
* ```typescript
|
|
200
|
+
* // Disconnect all cached abilities
|
|
201
|
+
* for (const ability of cache.getAll()) {
|
|
202
|
+
* await ability.__disconnect();
|
|
203
|
+
* }
|
|
204
|
+
* ```
|
|
205
|
+
*/
|
|
206
|
+
getAll(): LoadedAbility[];
|
|
207
|
+
/**
|
|
208
|
+
* Get cache statistics
|
|
209
|
+
*
|
|
210
|
+
* Returns info about cache state for debugging/monitoring.
|
|
211
|
+
*
|
|
212
|
+
* @returns Cache statistics
|
|
213
|
+
*
|
|
214
|
+
* @example
|
|
215
|
+
* ```typescript
|
|
216
|
+
* const stats = cache.getStats();
|
|
217
|
+
* console.log(`Cached: ${stats.totalCached}, Connected: ${stats.connected}`);
|
|
218
|
+
* ```
|
|
219
|
+
*/
|
|
220
|
+
getStats(): {
|
|
221
|
+
totalCached: number;
|
|
222
|
+
connected: number;
|
|
223
|
+
disconnected: number;
|
|
224
|
+
byTransport: Record<TransportType, number>;
|
|
225
|
+
};
|
|
226
|
+
/**
|
|
227
|
+
* Cleanup disconnected abilities
|
|
228
|
+
*
|
|
229
|
+
* Removes abilities that are no longer connected.
|
|
230
|
+
* Returns number of entries removed.
|
|
231
|
+
*
|
|
232
|
+
* @returns Number of stale entries removed
|
|
233
|
+
*
|
|
234
|
+
* @example
|
|
235
|
+
* ```typescript
|
|
236
|
+
* const removed = cache.cleanup();
|
|
237
|
+
* console.log(`Removed ${removed} disconnected abilities`);
|
|
238
|
+
* ```
|
|
239
|
+
*/
|
|
240
|
+
cleanup(): number;
|
|
241
|
+
}
|
|
242
|
+
//# sourceMappingURL=AbilityCache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AbilityCache.d.ts","sourceRoot":"","sources":["../../src/abilities/AbilityCache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD;;;;;GAKG;AACH,MAAM,WAAW,QAAQ;IACvB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;;OAIG;IACH,SAAS,EAAE,aAAa,CAAC;IAEzB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,qBAAa,YAAY;IACvB;;;;;OAKG;IACH,OAAO,CAAC,KAAK,CAAoC;IAEjD;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,OAAO,CAAC,WAAW;IAqBnB;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,GAAG,CAAC,GAAG,EAAE,QAAQ,GAAG,aAAa,GAAG,SAAS;IAkB7C;;;;;;;;;;;;;;;OAeG;IACH,GAAG,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,GAAG,IAAI;IAQhD;;;;;;;;;;;;;;OAcG;IACH,GAAG,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO;IAI3B;;;;;;;;;;OAUG;IACH,MAAM,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO;IAQ9B;;;;;;;;;;OAUG;IACH,KAAK,IAAI,IAAI;IAIb;;;;;;;;;;;;;;;OAeG;IACH,MAAM,IAAI,aAAa,EAAE;IAIzB;;;;;;;;;;;;OAYG;IACH,QAAQ,IAAI;QACV,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;QAClB,YAAY,EAAE,MAAM,CAAC;QACrB,WAAW,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;KAC5C;IA6BD;;;;;;;;;;;;;OAaG;IACH,OAAO,IAAI,MAAM;CAalB"}
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ability Cache
|
|
3
|
+
*
|
|
4
|
+
* Smart caching with composite keys to handle complex scenarios:
|
|
5
|
+
* - Same ability name, different transports
|
|
6
|
+
* - Same ability name, different versions
|
|
7
|
+
* - Same ability name, different brokers
|
|
8
|
+
*
|
|
9
|
+
* @module abilities/AbilityCache
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Ability Cache
|
|
13
|
+
*
|
|
14
|
+
* Intelligent caching that avoids loading same ability multiple times,
|
|
15
|
+
* while correctly handling scenarios where same name ≠ same ability.
|
|
16
|
+
*
|
|
17
|
+
* **Why Composite Keys?**
|
|
18
|
+
*
|
|
19
|
+
* Consider:
|
|
20
|
+
* ```typescript
|
|
21
|
+
* const local = await client.load('calc', { transport: 'native' });
|
|
22
|
+
* const remote = await client.load('calc', { transport: 'broker' });
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* These are DIFFERENT abilities (different implementations, different transports)
|
|
26
|
+
* despite having same name. Cache must treat them separately!
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* const cache = new AbilityCache();
|
|
31
|
+
*
|
|
32
|
+
* // Store ability
|
|
33
|
+
* cache.set({ name: 'calc', transport: 'broker' }, ability);
|
|
34
|
+
*
|
|
35
|
+
* // Retrieve ability
|
|
36
|
+
* const cached = cache.get({ name: 'calc', transport: 'broker' });
|
|
37
|
+
*
|
|
38
|
+
* // Different transport = different cache entry
|
|
39
|
+
* const notFound = cache.get({ name: 'calc', transport: 'native' });
|
|
40
|
+
* // Returns undefined (different transport)
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export class AbilityCache {
|
|
44
|
+
/**
|
|
45
|
+
* Internal cache storage
|
|
46
|
+
*
|
|
47
|
+
* Key: composite string (name:transport:version:broker)
|
|
48
|
+
* Value: loaded ability instance
|
|
49
|
+
*/
|
|
50
|
+
cache = new Map();
|
|
51
|
+
/**
|
|
52
|
+
* Generate composite cache key from components
|
|
53
|
+
*
|
|
54
|
+
* Format: `name:transport[:version][:broker]`
|
|
55
|
+
*
|
|
56
|
+
* Optional components only included if present:
|
|
57
|
+
* - Basic: "calculator:broker"
|
|
58
|
+
* - With version: "calculator:broker:2.0.0"
|
|
59
|
+
* - With broker: "calculator:broker::main-broker"
|
|
60
|
+
* - Full: "calculator:broker:2.0.0:main-broker"
|
|
61
|
+
*
|
|
62
|
+
* @param key - Cache key components
|
|
63
|
+
* @returns Composite key string
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```typescript
|
|
67
|
+
* generateKey({ name: 'calc', transport: 'broker' })
|
|
68
|
+
* // Returns: "calc:broker"
|
|
69
|
+
*
|
|
70
|
+
* generateKey({ name: 'calc', transport: 'broker', version: '2.0.0' })
|
|
71
|
+
* // Returns: "calc:broker:2.0.0"
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
generateKey(key) {
|
|
75
|
+
// Step 1: Start with required components
|
|
76
|
+
const parts = [key.name, key.transport];
|
|
77
|
+
// Step 2: Add optional version if present
|
|
78
|
+
if (key.version) {
|
|
79
|
+
parts.push(key.version);
|
|
80
|
+
}
|
|
81
|
+
else if (key.broker) {
|
|
82
|
+
// If broker but no version, add empty slot to maintain structure
|
|
83
|
+
parts.push('');
|
|
84
|
+
}
|
|
85
|
+
// Step 3: Add optional broker if present
|
|
86
|
+
if (key.broker) {
|
|
87
|
+
parts.push(key.broker);
|
|
88
|
+
}
|
|
89
|
+
// Step 4: Join with separator
|
|
90
|
+
return parts.join(':');
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Get cached ability
|
|
94
|
+
*
|
|
95
|
+
* Returns cached instance if exists and still connected.
|
|
96
|
+
* Returns undefined if not cached or disconnected.
|
|
97
|
+
*
|
|
98
|
+
* @param key - Cache key components
|
|
99
|
+
* @returns Cached ability or undefined
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* ```typescript
|
|
103
|
+
* const ability = cache.get({
|
|
104
|
+
* name: 'calculator',
|
|
105
|
+
* transport: 'broker'
|
|
106
|
+
* });
|
|
107
|
+
*
|
|
108
|
+
* if (ability) {
|
|
109
|
+
* // Cache hit! Use cached ability
|
|
110
|
+
* await ability.add({ a: 5, b: 3 });
|
|
111
|
+
* } else {
|
|
112
|
+
* // Cache miss - need to load
|
|
113
|
+
* }
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
get(key) {
|
|
117
|
+
// Step 1: Generate composite key
|
|
118
|
+
const cacheKey = this.generateKey(key);
|
|
119
|
+
// Step 2: Retrieve from cache
|
|
120
|
+
const ability = this.cache.get(cacheKey);
|
|
121
|
+
// Step 3: Validate still connected (defensive check)
|
|
122
|
+
if (ability && !ability.__isConnected()) {
|
|
123
|
+
// Disconnected ability - remove from cache
|
|
124
|
+
this.cache.delete(cacheKey);
|
|
125
|
+
return undefined;
|
|
126
|
+
}
|
|
127
|
+
// Step 4: Return cached ability
|
|
128
|
+
return ability;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Store ability in cache
|
|
132
|
+
*
|
|
133
|
+
* Overwrites existing entry if present.
|
|
134
|
+
*
|
|
135
|
+
* @param key - Cache key components
|
|
136
|
+
* @param ability - Loaded ability to cache
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* ```typescript
|
|
140
|
+
* cache.set(
|
|
141
|
+
* { name: 'calculator', transport: 'broker', version: '2.0.0' },
|
|
142
|
+
* loadedAbility
|
|
143
|
+
* );
|
|
144
|
+
* ```
|
|
145
|
+
*/
|
|
146
|
+
set(key, ability) {
|
|
147
|
+
// Step 1: Generate composite key
|
|
148
|
+
const cacheKey = this.generateKey(key);
|
|
149
|
+
// Step 2: Store in cache
|
|
150
|
+
this.cache.set(cacheKey, ability);
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Check if ability exists in cache
|
|
154
|
+
*
|
|
155
|
+
* Returns true only if cached AND still connected.
|
|
156
|
+
*
|
|
157
|
+
* @param key - Cache key components
|
|
158
|
+
* @returns true if cached and connected
|
|
159
|
+
*
|
|
160
|
+
* @example
|
|
161
|
+
* ```typescript
|
|
162
|
+
* if (cache.has({ name: 'calc', transport: 'broker' })) {
|
|
163
|
+
* // Can safely use cached version
|
|
164
|
+
* }
|
|
165
|
+
* ```
|
|
166
|
+
*/
|
|
167
|
+
has(key) {
|
|
168
|
+
return this.get(key) !== undefined;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Remove ability from cache
|
|
172
|
+
*
|
|
173
|
+
* @param key - Cache key components
|
|
174
|
+
* @returns true if was cached (now removed), false if wasn't cached
|
|
175
|
+
*
|
|
176
|
+
* @example
|
|
177
|
+
* ```typescript
|
|
178
|
+
* cache.delete({ name: 'calc', transport: 'broker' });
|
|
179
|
+
* ```
|
|
180
|
+
*/
|
|
181
|
+
delete(key) {
|
|
182
|
+
// Step 1: Generate composite key
|
|
183
|
+
const cacheKey = this.generateKey(key);
|
|
184
|
+
// Step 2: Remove from cache
|
|
185
|
+
return this.cache.delete(cacheKey);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Clear all cached abilities
|
|
189
|
+
*
|
|
190
|
+
* Removes everything from cache.
|
|
191
|
+
* Usually called during client disconnect/cleanup.
|
|
192
|
+
*
|
|
193
|
+
* @example
|
|
194
|
+
* ```typescript
|
|
195
|
+
* cache.clear();
|
|
196
|
+
* ```
|
|
197
|
+
*/
|
|
198
|
+
clear() {
|
|
199
|
+
this.cache.clear();
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Get all cached abilities
|
|
203
|
+
*
|
|
204
|
+
* Returns array of all cached ability instances.
|
|
205
|
+
* Useful for bulk operations like disconnect.
|
|
206
|
+
*
|
|
207
|
+
* @returns Array of loaded abilities
|
|
208
|
+
*
|
|
209
|
+
* @example
|
|
210
|
+
* ```typescript
|
|
211
|
+
* // Disconnect all cached abilities
|
|
212
|
+
* for (const ability of cache.getAll()) {
|
|
213
|
+
* await ability.__disconnect();
|
|
214
|
+
* }
|
|
215
|
+
* ```
|
|
216
|
+
*/
|
|
217
|
+
getAll() {
|
|
218
|
+
return Array.from(this.cache.values());
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Get cache statistics
|
|
222
|
+
*
|
|
223
|
+
* Returns info about cache state for debugging/monitoring.
|
|
224
|
+
*
|
|
225
|
+
* @returns Cache statistics
|
|
226
|
+
*
|
|
227
|
+
* @example
|
|
228
|
+
* ```typescript
|
|
229
|
+
* const stats = cache.getStats();
|
|
230
|
+
* console.log(`Cached: ${stats.totalCached}, Connected: ${stats.connected}`);
|
|
231
|
+
* ```
|
|
232
|
+
*/
|
|
233
|
+
getStats() {
|
|
234
|
+
let connected = 0;
|
|
235
|
+
let disconnected = 0;
|
|
236
|
+
const byTransport = {
|
|
237
|
+
broker: 0,
|
|
238
|
+
native: 0,
|
|
239
|
+
stdio: 0
|
|
240
|
+
};
|
|
241
|
+
// Analyze cache contents
|
|
242
|
+
for (const ability of this.cache.values()) {
|
|
243
|
+
if (ability.__isConnected()) {
|
|
244
|
+
connected++;
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
disconnected++;
|
|
248
|
+
}
|
|
249
|
+
const transport = ability.__transport;
|
|
250
|
+
byTransport[transport] = (byTransport[transport] || 0) + 1;
|
|
251
|
+
}
|
|
252
|
+
return {
|
|
253
|
+
totalCached: this.cache.size,
|
|
254
|
+
connected,
|
|
255
|
+
disconnected,
|
|
256
|
+
byTransport: byTransport
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Cleanup disconnected abilities
|
|
261
|
+
*
|
|
262
|
+
* Removes abilities that are no longer connected.
|
|
263
|
+
* Returns number of entries removed.
|
|
264
|
+
*
|
|
265
|
+
* @returns Number of stale entries removed
|
|
266
|
+
*
|
|
267
|
+
* @example
|
|
268
|
+
* ```typescript
|
|
269
|
+
* const removed = cache.cleanup();
|
|
270
|
+
* console.log(`Removed ${removed} disconnected abilities`);
|
|
271
|
+
* ```
|
|
272
|
+
*/
|
|
273
|
+
cleanup() {
|
|
274
|
+
let removed = 0;
|
|
275
|
+
// Find and remove disconnected abilities
|
|
276
|
+
for (const [key, ability] of this.cache.entries()) {
|
|
277
|
+
if (!ability.__isConnected()) {
|
|
278
|
+
this.cache.delete(key);
|
|
279
|
+
removed++;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
return removed;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
//# sourceMappingURL=AbilityCache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AbilityCache.js","sourceRoot":"","sources":["../../src/abilities/AbilityCache.ts"],"names":[],"mappings":"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"}
|