@advicenxt/sbp-server 0.1.0

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.
Files changed (63) hide show
  1. package/benchmarks/bench.ts +272 -0
  2. package/dist/auth.d.ts +20 -0
  3. package/dist/auth.d.ts.map +1 -0
  4. package/dist/auth.js +69 -0
  5. package/dist/auth.js.map +1 -0
  6. package/dist/blackboard.d.ts +84 -0
  7. package/dist/blackboard.d.ts.map +1 -0
  8. package/dist/blackboard.js +502 -0
  9. package/dist/blackboard.js.map +1 -0
  10. package/dist/cli.d.ts +7 -0
  11. package/dist/cli.d.ts.map +1 -0
  12. package/dist/cli.js +102 -0
  13. package/dist/cli.js.map +1 -0
  14. package/dist/conditions.d.ts +27 -0
  15. package/dist/conditions.d.ts.map +1 -0
  16. package/dist/conditions.js +240 -0
  17. package/dist/conditions.js.map +1 -0
  18. package/dist/decay.d.ts +21 -0
  19. package/dist/decay.d.ts.map +1 -0
  20. package/dist/decay.js +88 -0
  21. package/dist/decay.js.map +1 -0
  22. package/dist/index.d.ts +13 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +13 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/rate-limiter.d.ts +21 -0
  27. package/dist/rate-limiter.d.ts.map +1 -0
  28. package/dist/rate-limiter.js +75 -0
  29. package/dist/rate-limiter.js.map +1 -0
  30. package/dist/server.d.ts +63 -0
  31. package/dist/server.d.ts.map +1 -0
  32. package/dist/server.js +401 -0
  33. package/dist/server.js.map +1 -0
  34. package/dist/store.d.ts +54 -0
  35. package/dist/store.d.ts.map +1 -0
  36. package/dist/store.js +55 -0
  37. package/dist/store.js.map +1 -0
  38. package/dist/types.d.ts +247 -0
  39. package/dist/types.d.ts.map +1 -0
  40. package/dist/types.js +26 -0
  41. package/dist/types.js.map +1 -0
  42. package/dist/validation.d.ts +296 -0
  43. package/dist/validation.d.ts.map +1 -0
  44. package/dist/validation.js +205 -0
  45. package/dist/validation.js.map +1 -0
  46. package/eslint.config.js +26 -0
  47. package/package.json +66 -0
  48. package/src/auth.ts +89 -0
  49. package/src/blackboard.test.ts +287 -0
  50. package/src/blackboard.ts +651 -0
  51. package/src/cli.ts +116 -0
  52. package/src/conditions.ts +305 -0
  53. package/src/conformance.test.ts +686 -0
  54. package/src/decay.ts +103 -0
  55. package/src/index.ts +24 -0
  56. package/src/rate-limiter.ts +104 -0
  57. package/src/server.integration.test.ts +436 -0
  58. package/src/server.ts +500 -0
  59. package/src/store.ts +108 -0
  60. package/src/types.ts +314 -0
  61. package/src/validation.ts +251 -0
  62. package/tsconfig.eslint.json +5 -0
  63. package/tsconfig.json +20 -0
package/dist/server.js ADDED
@@ -0,0 +1,401 @@
1
+ /**
2
+ * SBP HTTP Server
3
+ * Streamable HTTP with SSE (following MCP transport patterns)
4
+ */
5
+ import Fastify from "fastify";
6
+ import { Blackboard } from "./blackboard.js";
7
+ import { v7 as uuidv7 } from "uuid";
8
+ import { validateEnvelope, validateParams } from "./validation.js";
9
+ import { createAuthHook } from "./auth.js";
10
+ import { createRateLimitHook } from "./rate-limiter.js";
11
+ export class SbpServer {
12
+ app;
13
+ blackboard;
14
+ options;
15
+ sseClients = new Map();
16
+ sessions = new Map();
17
+ eventCounter = 0;
18
+ constructor(options = {}) {
19
+ this.options = {
20
+ port: options.port ?? 3000,
21
+ host: options.host ?? "localhost",
22
+ cors: options.cors ?? true,
23
+ logging: options.logging ?? false,
24
+ evaluationInterval: options.evaluationInterval ?? 100,
25
+ defaultDecay: options.defaultDecay ?? { type: "exponential", half_life_ms: 300000 },
26
+ defaultTtlFloor: options.defaultTtlFloor ?? 0.01,
27
+ maxPheromones: options.maxPheromones ?? 100000,
28
+ trackEmissionHistory: options.trackEmissionHistory ?? true,
29
+ emissionHistoryWindow: options.emissionHistoryWindow ?? 60000,
30
+ auth: options.auth,
31
+ rateLimit: options.rateLimit,
32
+ };
33
+ this.blackboard = new Blackboard(this.options);
34
+ this.app = Fastify({ logger: this.options.logging });
35
+ this.setupRoutes();
36
+ }
37
+ setupRoutes() {
38
+ // Authentication hook
39
+ if (this.options.auth?.requireAuth) {
40
+ this.app.addHook("onRequest", createAuthHook(this.options.auth));
41
+ }
42
+ // Rate limiting hook
43
+ if (this.options.rateLimit) {
44
+ this.app.addHook("onRequest", createRateLimitHook(this.options.rateLimit));
45
+ }
46
+ // CORS
47
+ if (this.options.cors) {
48
+ this.app.addHook("onRequest", async (request, reply) => {
49
+ reply.header("Access-Control-Allow-Origin", "*");
50
+ reply.header("Access-Control-Allow-Methods", "POST, GET, DELETE, OPTIONS");
51
+ reply.header("Access-Control-Allow-Headers", "Content-Type, Accept, Authorization, Sbp-Protocol-Version, Sbp-Session-Id, Sbp-Agent-Id, Last-Event-ID");
52
+ if (request.method === "OPTIONS") {
53
+ reply.status(204).send();
54
+ }
55
+ });
56
+ }
57
+ // Health check
58
+ this.app.get("/health", async () => {
59
+ const stats = this.blackboard.inspect({ include: ["stats"] });
60
+ return {
61
+ status: "ok",
62
+ version: "0.1.0",
63
+ transport: "streamable-http-sse",
64
+ ...stats.stats,
65
+ };
66
+ });
67
+ // Main SBP endpoint - POST for client->server messages
68
+ this.app.post("/sbp", async (request, reply) => {
69
+ return this.handlePost(request, reply);
70
+ });
71
+ // Main SBP endpoint - GET for SSE stream (server->client)
72
+ this.app.get("/sbp", async (request, reply) => {
73
+ return this.handleSSE(request, reply);
74
+ });
75
+ // Legacy JSON-RPC endpoint (for backwards compatibility)
76
+ this.app.post("/rpc", async (request, reply) => {
77
+ const body = request.body;
78
+ const response = await this.handleRpc(body, request);
79
+ reply.header("Content-Type", "application/json");
80
+ return response;
81
+ });
82
+ // Convenience REST endpoints
83
+ this.app.post("/emit", async (request) => {
84
+ const params = request.body;
85
+ return this.blackboard.emit(params);
86
+ });
87
+ this.app.post("/sniff", async (request) => {
88
+ const params = request.body;
89
+ return this.blackboard.sniff(params);
90
+ });
91
+ this.app.post("/scents", async (request) => {
92
+ const params = request.body;
93
+ return this.blackboard.registerScent(params);
94
+ });
95
+ this.app.delete("/scents/:scent_id", async (request) => {
96
+ const { scent_id } = request.params;
97
+ return this.blackboard.deregisterScent({ scent_id });
98
+ });
99
+ this.app.get("/inspect", async (request) => {
100
+ const query = request.query;
101
+ const include = query.include?.split(",");
102
+ return this.blackboard.inspect({ include });
103
+ });
104
+ }
105
+ /**
106
+ * Handle POST requests (client -> server messages)
107
+ */
108
+ async handlePost(request, reply) {
109
+ // Validate JSON-RPC envelope
110
+ const envelopeResult = validateEnvelope(request.body);
111
+ if (!envelopeResult.ok) {
112
+ reply.header("Content-Type", "application/json");
113
+ return {
114
+ jsonrpc: "2.0",
115
+ id: null,
116
+ error: envelopeResult.error,
117
+ };
118
+ }
119
+ const body = envelopeResult.request;
120
+ // Validate method-specific params
121
+ const paramsResult = validateParams(body.method, body.params);
122
+ if (!paramsResult.ok) {
123
+ reply.header("Content-Type", "application/json");
124
+ return {
125
+ jsonrpc: "2.0",
126
+ id: body.id,
127
+ error: paramsResult.error,
128
+ };
129
+ }
130
+ // Replace params with validated (parsed) params
131
+ const validatedRequest = {
132
+ ...body,
133
+ params: paramsResult.params,
134
+ };
135
+ // Get or create session
136
+ let sessionId = request.headers["sbp-session-id"];
137
+ if (!sessionId) {
138
+ sessionId = uuidv7();
139
+ this.sessions.set(sessionId, {
140
+ agentId: request.headers["sbp-agent-id"] || "unknown",
141
+ createdAt: Date.now(),
142
+ });
143
+ }
144
+ // Handle JSON-RPC request
145
+ const response = await this.handleRpc(validatedRequest, request);
146
+ // Set session header
147
+ reply.header("Sbp-Session-Id", sessionId);
148
+ reply.header("Content-Type", "application/json");
149
+ return response;
150
+ }
151
+ /**
152
+ * Handle GET requests - open SSE stream for triggers
153
+ */
154
+ async handleSSE(request, reply) {
155
+ const accept = request.headers.accept || "";
156
+ if (!accept.includes("text/event-stream")) {
157
+ reply.status(406).send({ error: "Accept header must include text/event-stream" });
158
+ return;
159
+ }
160
+ const sessionId = request.headers["sbp-session-id"] || uuidv7();
161
+ const lastEventId = request.headers["last-event-id"];
162
+ const clientId = uuidv7();
163
+ // Set up SSE headers
164
+ reply.raw.writeHead(200, {
165
+ "Content-Type": "text/event-stream",
166
+ "Cache-Control": "no-cache",
167
+ Connection: "keep-alive",
168
+ "Sbp-Session-Id": sessionId,
169
+ "Access-Control-Allow-Origin": "*",
170
+ });
171
+ // Register SSE client
172
+ const client = {
173
+ id: clientId,
174
+ sessionId,
175
+ reply,
176
+ scents: new Set(),
177
+ lastEventId: lastEventId ? parseInt(lastEventId, 10) : 0,
178
+ };
179
+ this.sseClients.set(clientId, client);
180
+ // Send initial connection event
181
+ this.sendSSEEvent(client, "connected", { client_id: clientId, session_id: sessionId });
182
+ // Handle client disconnect
183
+ request.raw.on("close", () => {
184
+ this.sseClients.delete(clientId);
185
+ // Unregister scent handlers for this client
186
+ for (const scentId of client.scents) {
187
+ this.blackboard.offTrigger(scentId);
188
+ }
189
+ });
190
+ // Keep connection alive with periodic comments
191
+ const keepAlive = setInterval(() => {
192
+ if (reply.raw.writable) {
193
+ reply.raw.write(": keepalive\n\n");
194
+ }
195
+ else {
196
+ clearInterval(keepAlive);
197
+ }
198
+ }, 30000);
199
+ request.raw.on("close", () => clearInterval(keepAlive));
200
+ }
201
+ /**
202
+ * Send an SSE event to a client
203
+ */
204
+ sendSSEEvent(client, event, data) {
205
+ if (!client.reply.raw.writable)
206
+ return;
207
+ const eventId = ++this.eventCounter;
208
+ const payload = JSON.stringify(data);
209
+ client.reply.raw.write(`event: ${event}\n`);
210
+ client.reply.raw.write(`id: ${eventId}\n`);
211
+ client.reply.raw.write(`data: ${payload}\n\n`);
212
+ client.lastEventId = eventId;
213
+ }
214
+ /**
215
+ * Send a JSON-RPC notification via SSE
216
+ */
217
+ sendSSENotification(client, method, params) {
218
+ const message = {
219
+ jsonrpc: "2.0",
220
+ method,
221
+ params,
222
+ };
223
+ this.sendSSEEvent(client, "message", message);
224
+ }
225
+ /**
226
+ * Handle JSON-RPC requests
227
+ */
228
+ async handleRpc(request, httpRequest) {
229
+ const { id, method, params } = request;
230
+ const sessionId = httpRequest.headers["sbp-session-id"];
231
+ try {
232
+ let result;
233
+ switch (method) {
234
+ case "sbp/emit":
235
+ result = this.blackboard.emit(params);
236
+ break;
237
+ case "sbp/sniff":
238
+ result = this.blackboard.sniff(params);
239
+ break;
240
+ case "sbp/register_scent": {
241
+ const scentParams = params;
242
+ result = this.blackboard.registerScent(scentParams);
243
+ // Set up trigger forwarding
244
+ if (sessionId) {
245
+ this.setupSSETrigger(scentParams.scent_id, sessionId);
246
+ }
247
+ // If agent_endpoint is provided, set up webhook delivery
248
+ if (scentParams.agent_endpoint) {
249
+ this.setupWebhookTrigger(scentParams.scent_id, scentParams.agent_endpoint);
250
+ }
251
+ break;
252
+ }
253
+ case "sbp/deregister_scent":
254
+ result = this.blackboard.deregisterScent(params);
255
+ break;
256
+ case "sbp/evaporate":
257
+ result = this.blackboard.evaporate(params);
258
+ break;
259
+ case "sbp/inspect":
260
+ result = this.blackboard.inspect(params);
261
+ break;
262
+ case "sbp/subscribe": {
263
+ // Subscribe to scent triggers (used after SSE stream is open)
264
+ const { scent_id } = params;
265
+ if (sessionId) {
266
+ this.setupSSETrigger(scent_id, sessionId);
267
+ // Mark scent subscription for all clients in this session
268
+ for (const client of this.sseClients.values()) {
269
+ if (client.sessionId === sessionId) {
270
+ client.scents.add(scent_id);
271
+ }
272
+ }
273
+ }
274
+ result = { subscribed: scent_id };
275
+ break;
276
+ }
277
+ case "sbp/unsubscribe": {
278
+ const { scent_id } = params;
279
+ this.blackboard.offTrigger(scent_id);
280
+ // Remove from client scent sets
281
+ for (const client of this.sseClients.values()) {
282
+ if (client.sessionId === sessionId) {
283
+ client.scents.delete(scent_id);
284
+ }
285
+ }
286
+ result = { unsubscribed: scent_id };
287
+ break;
288
+ }
289
+ default:
290
+ return {
291
+ jsonrpc: "2.0",
292
+ id,
293
+ error: {
294
+ code: -32601,
295
+ message: "Method not found",
296
+ data: { method },
297
+ },
298
+ };
299
+ }
300
+ return {
301
+ jsonrpc: "2.0",
302
+ id,
303
+ result,
304
+ };
305
+ }
306
+ catch (err) {
307
+ const error = err;
308
+ return {
309
+ jsonrpc: "2.0",
310
+ id,
311
+ error: {
312
+ code: -32603,
313
+ message: error.message,
314
+ },
315
+ };
316
+ }
317
+ }
318
+ /**
319
+ * Set up trigger forwarding to SSE clients
320
+ */
321
+ setupSSETrigger(scentId, sessionId) {
322
+ this.blackboard.onTrigger(scentId, async (payload) => {
323
+ // Send to all SSE clients in this session
324
+ for (const client of this.sseClients.values()) {
325
+ if (client.sessionId === sessionId || client.scents.has(scentId)) {
326
+ this.sendSSENotification(client, "sbp/trigger", payload);
327
+ }
328
+ }
329
+ });
330
+ }
331
+ /**
332
+ * Set up webhook trigger delivery to an agent endpoint
333
+ */
334
+ setupWebhookTrigger(scentId, endpoint) {
335
+ this.blackboard.onTrigger(scentId, async (payload) => {
336
+ // Attempt webhook delivery with one retry
337
+ for (let attempt = 0; attempt < 2; attempt++) {
338
+ try {
339
+ const response = await fetch(endpoint, {
340
+ method: "POST",
341
+ headers: {
342
+ "Content-Type": "application/json",
343
+ "Sbp-Protocol-Version": "0.1",
344
+ },
345
+ body: JSON.stringify({
346
+ jsonrpc: "2.0",
347
+ method: "sbp/trigger",
348
+ params: payload,
349
+ }),
350
+ signal: AbortSignal.timeout(10000),
351
+ });
352
+ if (response.ok)
353
+ return; // Success
354
+ // Retry on 5xx
355
+ if (response.status >= 500 && attempt === 0) {
356
+ await new Promise((r) => setTimeout(r, 1000));
357
+ continue;
358
+ }
359
+ break; // Don't retry on 4xx
360
+ }
361
+ catch {
362
+ // Network error — retry once
363
+ if (attempt === 0) {
364
+ await new Promise((r) => setTimeout(r, 1000));
365
+ }
366
+ }
367
+ }
368
+ });
369
+ }
370
+ async start() {
371
+ // Start blackboard evaluation loop
372
+ this.blackboard.start();
373
+ // Start HTTP server
374
+ await this.app.listen({ port: this.options.port, host: this.options.host });
375
+ console.log(`[SBP] Server listening on http://${this.options.host}:${this.options.port}`);
376
+ console.log(`[SBP] Streamable HTTP endpoint: POST/GET ${this.address}/sbp`);
377
+ console.log(`[SBP] Transport: SSE (Server-Sent Events)`);
378
+ if (this.options.auth?.requireAuth) {
379
+ console.log(`[SBP] Authentication: API key required`);
380
+ }
381
+ if (this.options.rateLimit) {
382
+ console.log(`[SBP] Rate limiting: ${this.options.rateLimit.maxRequests ?? 1000} req/${(this.options.rateLimit.windowMs ?? 60000) / 1000}s`);
383
+ }
384
+ }
385
+ async stop() {
386
+ this.blackboard.stop();
387
+ // Close all SSE connections
388
+ for (const client of this.sseClients.values()) {
389
+ if (client.reply.raw.writable) {
390
+ client.reply.raw.end();
391
+ }
392
+ }
393
+ this.sseClients.clear();
394
+ await this.app.close();
395
+ console.log("[SBP] Server stopped");
396
+ }
397
+ get address() {
398
+ return `http://${this.options.host}:${this.options.port}`;
399
+ }
400
+ }
401
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * SBP Pheromone Store - Persistence Adapter Interface
3
+ *
4
+ * Abstraction layer for pluggable storage backends.
5
+ * Default implementation: MemoryStore (in-process Map).
6
+ */
7
+ import type { Pheromone } from "./types.js";
8
+ /**
9
+ * Abstract storage interface for pheromones.
10
+ * Implementations MUST be synchronous-safe for the core Blackboard operations.
11
+ * Async-capable stores (Redis, SQLite) should pre-load into a local cache.
12
+ */
13
+ export interface PheromoneStore {
14
+ /** Get a pheromone by ID. Returns undefined if not found. */
15
+ get(id: string): Pheromone | undefined;
16
+ /** Store or update a pheromone. */
17
+ set(id: string, pheromone: Pheromone): void;
18
+ /** Delete a pheromone by ID. Returns true if existed. */
19
+ delete(id: string): boolean;
20
+ /** Check if a pheromone exists. */
21
+ has(id: string): boolean;
22
+ /** Iterate over all stored pheromones. */
23
+ values(): IterableIterator<Pheromone>;
24
+ /** Iterate over all [id, pheromone] pairs. */
25
+ entries(): IterableIterator<[string, Pheromone]>;
26
+ /** Number of stored pheromones. */
27
+ readonly size: number;
28
+ /** Remove all pheromones. */
29
+ clear(): void;
30
+ }
31
+ /**
32
+ * In-memory pheromone store backed by a Map.
33
+ * This is the default store and provides the fastest access.
34
+ * Data is lost on process restart — acceptable for ephemeral signals.
35
+ */
36
+ export declare class MemoryStore implements PheromoneStore {
37
+ private data;
38
+ get(id: string): Pheromone | undefined;
39
+ set(id: string, pheromone: Pheromone): void;
40
+ delete(id: string): boolean;
41
+ has(id: string): boolean;
42
+ values(): IterableIterator<Pheromone>;
43
+ entries(): IterableIterator<[string, Pheromone]>;
44
+ get size(): number;
45
+ clear(): void;
46
+ }
47
+ export type StoreType = "memory";
48
+ /**
49
+ * Create a pheromone store of the specified type.
50
+ * Currently only "memory" is built-in. Additional stores (Redis, SQLite)
51
+ * can be added by implementing the PheromoneStore interface.
52
+ */
53
+ export declare function createStore(type?: StoreType): PheromoneStore;
54
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAM5C;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC3B,6DAA6D;IAC7D,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;IAEvC,mCAAmC;IACnC,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IAE5C,yDAAyD;IACzD,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IAE5B,mCAAmC;IACnC,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IAEzB,0CAA0C;IAC1C,MAAM,IAAI,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAEtC,8CAA8C;IAC9C,OAAO,IAAI,gBAAgB,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;IAEjD,mCAAmC;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,6BAA6B;IAC7B,KAAK,IAAI,IAAI,CAAC;CACjB;AAMD;;;;GAIG;AACH,qBAAa,WAAY,YAAW,cAAc;IAC9C,OAAO,CAAC,IAAI,CAAgC;IAE5C,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAItC,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,GAAG,IAAI;IAI3C,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAI3B,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAIxB,MAAM,IAAI,gBAAgB,CAAC,SAAS,CAAC;IAIrC,OAAO,IAAI,gBAAgB,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAIhD,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,KAAK,IAAI,IAAI;CAGhB;AAMD,MAAM,MAAM,SAAS,GAAG,QAAQ,CAAC;AAEjC;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,GAAE,SAAoB,GAAG,cAAc,CAOtE"}
package/dist/store.js ADDED
@@ -0,0 +1,55 @@
1
+ /**
2
+ * SBP Pheromone Store - Persistence Adapter Interface
3
+ *
4
+ * Abstraction layer for pluggable storage backends.
5
+ * Default implementation: MemoryStore (in-process Map).
6
+ */
7
+ // ============================================================================
8
+ // MEMORY STORE
9
+ // ============================================================================
10
+ /**
11
+ * In-memory pheromone store backed by a Map.
12
+ * This is the default store and provides the fastest access.
13
+ * Data is lost on process restart — acceptable for ephemeral signals.
14
+ */
15
+ export class MemoryStore {
16
+ data = new Map();
17
+ get(id) {
18
+ return this.data.get(id);
19
+ }
20
+ set(id, pheromone) {
21
+ this.data.set(id, pheromone);
22
+ }
23
+ delete(id) {
24
+ return this.data.delete(id);
25
+ }
26
+ has(id) {
27
+ return this.data.has(id);
28
+ }
29
+ values() {
30
+ return this.data.values();
31
+ }
32
+ entries() {
33
+ return this.data.entries();
34
+ }
35
+ get size() {
36
+ return this.data.size;
37
+ }
38
+ clear() {
39
+ this.data.clear();
40
+ }
41
+ }
42
+ /**
43
+ * Create a pheromone store of the specified type.
44
+ * Currently only "memory" is built-in. Additional stores (Redis, SQLite)
45
+ * can be added by implementing the PheromoneStore interface.
46
+ */
47
+ export function createStore(type = "memory") {
48
+ switch (type) {
49
+ case "memory":
50
+ return new MemoryStore();
51
+ default:
52
+ throw new Error(`Unknown store type: ${type}`);
53
+ }
54
+ }
55
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAuCH,+EAA+E;AAC/E,eAAe;AACf,+EAA+E;AAE/E;;;;GAIG;AACH,MAAM,OAAO,WAAW;IACZ,IAAI,GAAG,IAAI,GAAG,EAAqB,CAAC;IAE5C,GAAG,CAAC,EAAU;QACV,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC7B,CAAC;IAED,GAAG,CAAC,EAAU,EAAE,SAAoB;QAChC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;IACjC,CAAC;IAED,MAAM,CAAC,EAAU;QACb,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAChC,CAAC;IAED,GAAG,CAAC,EAAU;QACV,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC7B,CAAC;IAED,MAAM;QACF,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;IAC9B,CAAC;IAED,OAAO;QACH,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;IAC/B,CAAC;IAED,IAAI,IAAI;QACJ,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IAC1B,CAAC;IAED,KAAK;QACD,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;IACtB,CAAC;CACJ;AAQD;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,OAAkB,QAAQ;IAClD,QAAQ,IAAI,EAAE,CAAC;QACX,KAAK,QAAQ;YACT,OAAO,IAAI,WAAW,EAAE,CAAC;QAC7B;YACI,MAAM,IAAI,KAAK,CAAC,uBAAuB,IAAI,EAAE,CAAC,CAAC;IACvD,CAAC;AACL,CAAC"}