@kb-labs/core-state-daemon 2.112.0 → 2.114.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.
package/dist/index.d.ts CHANGED
@@ -11,11 +11,9 @@ declare class StateDaemonServer {
11
11
  private readonly observability;
12
12
  private readonly logger;
13
13
  private server;
14
- private isShuttingDown;
15
14
  constructor(config?: StateDaemonConfig);
16
15
  start(): Promise<void>;
17
16
  stop(): Promise<void>;
18
- private shutdown;
19
17
  private getBrokerHealth;
20
18
  private getBrokerStats;
21
19
  private registerRoutes;
package/dist/index.js CHANGED
@@ -1,71 +1,30 @@
1
1
  import Fastify from 'fastify';
2
2
  import { InMemoryStateBroker } from '@kb-labs/core-state-broker';
3
- import { HttpObservabilityCollector, createCorrelatedLogger, registerOpenAPI, getListenOptions, createServiceReadyResponse, metricLine } from '@kb-labs/shared-http';
3
+ import { createContextLogger } from '@kb-labs/core-platform';
4
+ import { ConsoleLogger } from '@kb-labs/core-platform/inmemory';
5
+ import { HttpObservabilityCollector, createHttpLogger, registerOpenAPI, getListenOptions, createServiceReadyResponse, metricLine } from '@kb-labs/shared-http';
4
6
  import { randomUUID } from 'crypto';
5
- import { createServiceBootstrap } from '@kb-labs/core-runtime';
6
7
  import { makeAssemblyHook } from '@kb-labs/plugin-runtime';
7
- import { runDaemon } from '@kb-labs/shared-daemon';
8
+ import { runService } from '@kb-labs/shared-daemon';
8
9
 
9
10
  // src/server.ts
10
11
  function createFallbackLogger() {
11
- const bindings = {};
12
- const formatMeta = (meta) => {
13
- const combined = { ...bindings, ...meta ?? {} };
14
- return Object.keys(combined).length > 0 ? ` ${JSON.stringify(combined)}` : "";
15
- };
16
- return {
17
- info(message, meta) {
18
- console.log(`[INFO] ${message}${formatMeta(meta)}`);
19
- },
20
- warn(message, meta) {
21
- console.warn(`[WARN] ${message}${formatMeta(meta)}`);
22
- },
23
- error(message, error, meta) {
24
- const merged = error ? { ...meta ?? {}, error: { message: error.message, stack: error.stack } } : meta;
25
- console.error(`[ERROR] ${message}${formatMeta(merged)}`);
26
- },
27
- fatal(message, error, meta) {
28
- const merged = error ? { ...meta ?? {}, error: { message: error.message, stack: error.stack } } : meta;
29
- console.error(`[FATAL] ${message}${formatMeta(merged)}`);
30
- },
31
- debug(message, meta) {
32
- console.debug(`[DEBUG] ${message}${formatMeta(meta)}`);
33
- },
34
- trace(message, meta) {
35
- console.debug(`[TRACE] ${message}${formatMeta(meta)}`);
36
- },
37
- child(childBindings) {
38
- const childLogger = createFallbackLogger();
39
- return {
40
- ...childLogger,
41
- info(message, meta) {
42
- console.log(`[INFO] ${message}${formatMeta({ ...childBindings, ...meta ?? {} })}`);
43
- },
44
- warn(message, meta) {
45
- console.warn(`[WARN] ${message}${formatMeta({ ...childBindings, ...meta ?? {} })}`);
46
- },
47
- error(message, error, meta) {
48
- const merged = error ? { ...childBindings, ...meta ?? {}, error: { message: error.message, stack: error.stack } } : { ...childBindings, ...meta ?? {} };
49
- console.error(`[ERROR] ${message}${formatMeta(merged)}`);
50
- },
51
- fatal(message, error, meta) {
52
- const merged = error ? { ...childBindings, ...meta ?? {}, error: { message: error.message, stack: error.stack } } : { ...childBindings, ...meta ?? {} };
53
- console.error(`[FATAL] ${message}${formatMeta(merged)}`);
54
- },
55
- debug(message, meta) {
56
- console.debug(`[DEBUG] ${message}${formatMeta({ ...childBindings, ...meta ?? {} })}`);
57
- },
58
- trace(message, meta) {
59
- console.debug(`[TRACE] ${message}${formatMeta({ ...childBindings, ...meta ?? {} })}`);
60
- }
61
- };
62
- }
63
- };
12
+ return createContextLogger(new ConsoleLogger(), {
13
+ applicationId: "kb-labs",
14
+ serviceId: "state-daemon",
15
+ instanceId: `local:${process.pid}`,
16
+ layer: "service"
17
+ });
64
18
  }
65
19
  var StateDaemonServer = class {
66
20
  constructor(config = {}) {
67
21
  this.config = config;
68
- this.logger = config.logger ?? createFallbackLogger();
22
+ this.logger = createContextLogger(config.logger ?? createFallbackLogger(), {
23
+ applicationId: "kb-labs",
24
+ serviceId: "state-daemon",
25
+ instanceId: `local:${process.pid}`,
26
+ layer: "service"
27
+ });
69
28
  }
70
29
  config;
71
30
  broker = new InMemoryStateBroker();
@@ -77,7 +36,6 @@ var StateDaemonServer = class {
77
36
  });
78
37
  logger;
79
38
  server = null;
80
- isShuttingDown = false;
81
39
  async start() {
82
40
  const port = this.config.port ?? 7777;
83
41
  const host = this.config.host ?? "localhost";
@@ -91,18 +49,17 @@ var StateDaemonServer = class {
91
49
  request.id = requestId;
92
50
  reply.header("X-Request-Id", requestId);
93
51
  reply.header("X-Trace-Id", traceId);
94
- request.kbLogger = createCorrelatedLogger(this.logger, {
52
+ request.kbLogger = createHttpLogger(this.logger, {
95
53
  serviceId: "state-daemon",
96
- logsSource: "state-daemon",
97
- layer: "state-daemon",
98
- service: "request",
54
+ layer: "service",
55
+ component: "http-request",
99
56
  requestId,
100
57
  traceId,
101
58
  method: request.method,
102
59
  url: request.url,
103
60
  operation: "http.request"
104
61
  });
105
- request.kbLogger.info(`\u2192 ${request.method.toUpperCase()} ${request.url}`);
62
+ request.kbLogger.debug("HTTP request started");
106
63
  if (request.method === "OPTIONS") {
107
64
  reply.code(204).send();
108
65
  }
@@ -112,13 +69,16 @@ var StateDaemonServer = class {
112
69
  if (!logger) {
113
70
  return;
114
71
  }
115
- logger.info(`\u2713 ${request.method.toUpperCase()} ${request.url} ${reply.statusCode}`, {
116
- statusCode: reply.statusCode
72
+ logger.info("HTTP request completed", {
73
+ "http.status_code": reply.statusCode
117
74
  });
118
75
  });
119
76
  server.addHook("onSend", async (_request, reply, payload) => {
120
77
  reply.header("Access-Control-Allow-Origin", "*");
121
- reply.header("Access-Control-Allow-Methods", "GET, PUT, DELETE, POST, OPTIONS");
78
+ reply.header(
79
+ "Access-Control-Allow-Methods",
80
+ "GET, PUT, DELETE, POST, OPTIONS"
81
+ );
122
82
  reply.header("Access-Control-Allow-Headers", "Content-Type");
123
83
  return payload;
124
84
  });
@@ -142,20 +102,17 @@ var StateDaemonServer = class {
142
102
  this.server = null;
143
103
  }
144
104
  }
145
- async shutdown() {
146
- if (this.isShuttingDown) {
147
- return;
148
- }
149
- this.isShuttingDown = true;
150
- this.logger.info("Shutting down state daemon...");
151
- await this.stop();
152
- process.exit(0);
153
- }
154
105
  getBrokerHealth() {
155
- return this.observability.observeOperation("state.health", () => this.broker.getHealth());
106
+ return this.observability.observeOperation(
107
+ "state.health",
108
+ () => this.broker.getHealth()
109
+ );
156
110
  }
157
111
  getBrokerStats() {
158
- return this.observability.observeOperation("state.stats", () => this.broker.getStats());
112
+ return this.observability.observeOperation(
113
+ "state.stats",
114
+ () => this.broker.getStats()
115
+ );
159
116
  }
160
117
  registerRoutes(server) {
161
118
  server.get("/health", async () => this.getBrokerHealth());
@@ -184,7 +141,10 @@ var StateDaemonServer = class {
184
141
  buildBrokerMetricLines(stats)
185
142
  );
186
143
  });
187
- server.get("/observability/describe", async () => this.observability.buildDescribe());
144
+ server.get(
145
+ "/observability/describe",
146
+ async () => this.observability.buildDescribe()
147
+ );
188
148
  server.get("/observability/health", async () => {
189
149
  const health = await this.getBrokerHealth();
190
150
  const stats = await this.getBrokerStats();
@@ -204,7 +164,10 @@ var StateDaemonServer = class {
204
164
  });
205
165
  server.get("/state/:key", async (request, reply) => {
206
166
  const { key } = request.params;
207
- const value = await this.observability.observeOperation("state.get", () => this.broker.get(key));
167
+ const value = await this.observability.observeOperation(
168
+ "state.get",
169
+ () => this.broker.get(key)
170
+ );
208
171
  if (value === null) {
209
172
  reply.code(404);
210
173
  return null;
@@ -215,47 +178,68 @@ var StateDaemonServer = class {
215
178
  server.put("/state/:key", async (request, reply) => {
216
179
  const { key } = request.params;
217
180
  const { value, ttl } = request.body;
218
- await this.observability.observeOperation("state.set", () => this.broker.set(key, value, ttl));
181
+ await this.observability.observeOperation(
182
+ "state.set",
183
+ () => this.broker.set(key, value, ttl)
184
+ );
219
185
  reply.code(204);
220
186
  return null;
221
187
  });
222
188
  server.put("/state/:key/if-absent", async (request, reply) => {
223
189
  const { key } = request.params;
224
190
  const { value, ttl } = request.body;
225
- const inserted = await this.observability.observeOperation("state.setIfNotExists", () => this.broker.setIfNotExists(key, value, ttl));
191
+ const inserted = await this.observability.observeOperation(
192
+ "state.setIfNotExists",
193
+ () => this.broker.setIfNotExists(key, value, ttl)
194
+ );
226
195
  reply.code(inserted ? 204 : 409);
227
196
  return null;
228
197
  });
229
198
  server.put("/state/:key/zset", async (request, reply) => {
230
199
  const { key } = request.params;
231
200
  const { score, member } = request.body;
232
- await this.observability.observeOperation("state.zadd", () => this.broker.zadd(key, score, member));
201
+ await this.observability.observeOperation(
202
+ "state.zadd",
203
+ () => this.broker.zadd(key, score, member)
204
+ );
233
205
  reply.code(204);
234
206
  return null;
235
207
  });
236
208
  server.delete("/state/:key/zset", async (request, reply) => {
237
209
  const { key } = request.params;
238
210
  const { member } = request.body;
239
- await this.observability.observeOperation("state.zrem", () => this.broker.zrem(key, member));
211
+ await this.observability.observeOperation(
212
+ "state.zrem",
213
+ () => this.broker.zrem(key, member)
214
+ );
240
215
  reply.code(204);
241
216
  return null;
242
217
  });
243
218
  server.get("/state/:key/range", async (request, reply) => {
244
219
  const { key } = request.params;
245
220
  const query = request.query;
246
- const members = await this.observability.observeOperation("state.zrangebyscore", () => this.broker.zrangebyscore(key, Number(query.min), Number(query.max)));
221
+ const members = await this.observability.observeOperation(
222
+ "state.zrangebyscore",
223
+ () => this.broker.zrangebyscore(key, Number(query.min), Number(query.max))
224
+ );
247
225
  reply.type("application/json");
248
226
  return members;
249
227
  });
250
228
  server.delete("/state/:key", async (request, reply) => {
251
229
  const { key } = request.params;
252
- await this.observability.observeOperation("state.delete", () => this.broker.delete(key));
230
+ await this.observability.observeOperation(
231
+ "state.delete",
232
+ () => this.broker.delete(key)
233
+ );
253
234
  reply.code(204);
254
235
  return null;
255
236
  });
256
237
  server.post("/state/clear", async (request, reply) => {
257
238
  const pattern = request.query.pattern;
258
- await this.observability.observeOperation("state.clear", () => this.broker.clear(pattern));
239
+ await this.observability.observeOperation(
240
+ "state.clear",
241
+ () => this.broker.clear(pattern)
242
+ );
259
243
  reply.code(204);
260
244
  return null;
261
245
  });
@@ -293,21 +277,26 @@ function buildBrokerMetricLines(stats) {
293
277
  ];
294
278
  }
295
279
  async function bootstrap(_cwd = process.cwd()) {
296
- await runDaemon(
297
- {
298
- appId: "state-daemon",
299
- defaultPort: 7777,
300
- portEnvVar: "KB_STATE_DAEMON_PORT",
301
- defaultHost: "localhost",
302
- hostEnvVar: "KB_STATE_DAEMON_HOST",
303
- async setup({ platform, port, host }) {
304
- const server = new StateDaemonServer({ port, host, logger: platform.logger });
305
- await server.start();
306
- return () => server.stop();
307
- }
280
+ await runService({
281
+ appId: "state-daemon",
282
+ startDir: _cwd,
283
+ defaultPort: 7777,
284
+ portEnvVar: "KB_STATE_DAEMON_PORT",
285
+ defaultHost: "localhost",
286
+ hostEnvVar: "KB_STATE_DAEMON_HOST",
287
+ platform: {
288
+ assemblyHook: makeAssemblyHook()
308
289
  },
309
- (appId, repoRoot) => createServiceBootstrap({ appId, repoRoot, assemblyHook: makeAssemblyHook() })
310
- );
290
+ async setup({ port, host, logger }) {
291
+ const server = new StateDaemonServer({
292
+ port,
293
+ host,
294
+ logger
295
+ });
296
+ await server.start();
297
+ return () => server.stop();
298
+ }
299
+ });
311
300
  }
312
301
 
313
302
  export { StateDaemonServer, bootstrap };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/server.ts","../src/bootstrap.ts"],"names":[],"mappings":";;;;;;;;;AAoBA,SAAS,oBAAA,GAAgC;AACvC,EAAA,MAAM,WAAoC,EAAC;AAE3C,EAAA,MAAM,UAAA,GAAa,CAAC,IAAA,KAAmC;AACrD,IAAA,MAAM,WAAW,EAAE,GAAG,UAAU,GAAI,IAAA,IAAQ,EAAC,EAAG;AAChD,IAAA,OAAO,MAAA,CAAO,IAAA,CAAK,QAAQ,CAAA,CAAE,MAAA,GAAS,CAAA,GAAI,CAAA,CAAA,EAAI,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAC,CAAA,CAAA,GAAK,EAAA;AAAA,EAC7E,CAAA;AAEA,EAAA,OAAO;AAAA,IACL,IAAA,CAAK,SAAiB,IAAA,EAAgC;AACpD,MAAA,OAAA,CAAQ,IAAI,CAAA,OAAA,EAAU,OAAO,GAAG,UAAA,CAAW,IAAI,CAAC,CAAA,CAAE,CAAA;AAAA,IACpD,CAAA;AAAA,IACA,IAAA,CAAK,SAAiB,IAAA,EAAgC;AACpD,MAAA,OAAA,CAAQ,KAAK,CAAA,OAAA,EAAU,OAAO,GAAG,UAAA,CAAW,IAAI,CAAC,CAAA,CAAE,CAAA;AAAA,IACrD,CAAA;AAAA,IACA,KAAA,CAAM,OAAA,EAAiB,KAAA,EAAe,IAAA,EAAgC;AACpE,MAAA,MAAM,SAAS,KAAA,GACX,EAAE,GAAI,IAAA,IAAQ,EAAC,EAAI,KAAA,EAAO,EAAE,OAAA,EAAS,MAAM,OAAA,EAAS,KAAA,EAAO,KAAA,CAAM,KAAA,IAAQ,GACzE,IAAA;AACJ,MAAA,OAAA,CAAQ,MAAM,CAAA,QAAA,EAAW,OAAO,GAAG,UAAA,CAAW,MAAM,CAAC,CAAA,CAAE,CAAA;AAAA,IACzD,CAAA;AAAA,IACA,KAAA,CAAM,OAAA,EAAiB,KAAA,EAAe,IAAA,EAAgC;AACpE,MAAA,MAAM,SAAS,KAAA,GACX,EAAE,GAAI,IAAA,IAAQ,EAAC,EAAI,KAAA,EAAO,EAAE,OAAA,EAAS,MAAM,OAAA,EAAS,KAAA,EAAO,KAAA,CAAM,KAAA,IAAQ,GACzE,IAAA;AACJ,MAAA,OAAA,CAAQ,MAAM,CAAA,QAAA,EAAW,OAAO,GAAG,UAAA,CAAW,MAAM,CAAC,CAAA,CAAE,CAAA;AAAA,IACzD,CAAA;AAAA,IACA,KAAA,CAAM,SAAiB,IAAA,EAAgC;AACrD,MAAA,OAAA,CAAQ,MAAM,CAAA,QAAA,EAAW,OAAO,GAAG,UAAA,CAAW,IAAI,CAAC,CAAA,CAAE,CAAA;AAAA,IACvD,CAAA;AAAA,IACA,KAAA,CAAM,SAAiB,IAAA,EAAgC;AACrD,MAAA,OAAA,CAAQ,MAAM,CAAA,QAAA,EAAW,OAAO,GAAG,UAAA,CAAW,IAAI,CAAC,CAAA,CAAE,CAAA;AAAA,IACvD,CAAA;AAAA,IACA,MAAM,aAAA,EAAwC;AAC5C,MAAA,MAAM,cAAc,oBAAA,EAAqB;AACzC,MAAA,OAAO;AAAA,QACL,GAAG,WAAA;AAAA,QACH,IAAA,CAAK,SAAiB,IAAA,EAAgC;AACpD,UAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,OAAA,EAAU,OAAO,CAAA,EAAG,WAAW,EAAE,GAAG,aAAA,EAAe,GAAI,IAAA,IAAQ,EAAC,EAAI,CAAC,CAAA,CAAE,CAAA;AAAA,QACrF,CAAA;AAAA,QACA,IAAA,CAAK,SAAiB,IAAA,EAAgC;AACpD,UAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,OAAA,EAAU,OAAO,CAAA,EAAG,WAAW,EAAE,GAAG,aAAA,EAAe,GAAI,IAAA,IAAQ,EAAC,EAAI,CAAC,CAAA,CAAE,CAAA;AAAA,QACtF,CAAA;AAAA,QACA,KAAA,CAAM,OAAA,EAAiB,KAAA,EAAe,IAAA,EAAgC;AACpE,UAAA,MAAM,MAAA,GAAS,KAAA,GACX,EAAE,GAAG,aAAA,EAAe,GAAI,IAAA,IAAQ,EAAC,EAAI,KAAA,EAAO,EAAE,OAAA,EAAS,MAAM,OAAA,EAAS,KAAA,EAAO,KAAA,CAAM,KAAA,EAAM,EAAE,GAC3F,EAAE,GAAG,aAAA,EAAe,GAAI,IAAA,IAAQ,EAAC,EAAG;AACxC,UAAA,OAAA,CAAQ,MAAM,CAAA,QAAA,EAAW,OAAO,GAAG,UAAA,CAAW,MAAM,CAAC,CAAA,CAAE,CAAA;AAAA,QACzD,CAAA;AAAA,QACA,KAAA,CAAM,OAAA,EAAiB,KAAA,EAAe,IAAA,EAAgC;AACpE,UAAA,MAAM,MAAA,GAAS,KAAA,GACX,EAAE,GAAG,aAAA,EAAe,GAAI,IAAA,IAAQ,EAAC,EAAI,KAAA,EAAO,EAAE,OAAA,EAAS,MAAM,OAAA,EAAS,KAAA,EAAO,KAAA,CAAM,KAAA,EAAM,EAAE,GAC3F,EAAE,GAAG,aAAA,EAAe,GAAI,IAAA,IAAQ,EAAC,EAAG;AACxC,UAAA,OAAA,CAAQ,MAAM,CAAA,QAAA,EAAW,OAAO,GAAG,UAAA,CAAW,MAAM,CAAC,CAAA,CAAE,CAAA;AAAA,QACzD,CAAA;AAAA,QACA,KAAA,CAAM,SAAiB,IAAA,EAAgC;AACrD,UAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,QAAA,EAAW,OAAO,CAAA,EAAG,WAAW,EAAE,GAAG,aAAA,EAAe,GAAI,IAAA,IAAQ,EAAC,EAAI,CAAC,CAAA,CAAE,CAAA;AAAA,QACxF,CAAA;AAAA,QACA,KAAA,CAAM,SAAiB,IAAA,EAAgC;AACrD,UAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,QAAA,EAAW,OAAO,CAAA,EAAG,WAAW,EAAE,GAAG,aAAA,EAAe,GAAI,IAAA,IAAQ,EAAC,EAAI,CAAC,CAAA,CAAE,CAAA;AAAA,QACxF;AAAA,OACF;AAAA,IACF;AAAA,GACF;AACF;AAEO,IAAM,oBAAN,MAAwB;AAAA,EAY7B,WAAA,CAA6B,MAAA,GAA4B,EAAC,EAAG;AAAhC,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAC3B,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA,CAAO,MAAA,IAAU,oBAAA,EAAqB;AAAA,EACtD;AAAA,EAF6B,MAAA;AAAA,EAXZ,MAAA,GAAS,IAAI,mBAAA,EAAoB;AAAA,EACjC,aAAA,GAAgB,IAAI,0BAAA,CAA2B;AAAA,IAC9D,SAAA,EAAW,cAAA;AAAA,IACX,WAAA,EAAa,cAAA;AAAA,IACb,OAAA,EAAS,OAAA;AAAA,IACT,UAAA,EAAY;AAAA,GACb,CAAA;AAAA,EACgB,MAAA;AAAA,EACT,MAAA,GAAiC,IAAA;AAAA,EACjC,cAAA,GAAiB,KAAA;AAAA,EAMzB,MAAM,KAAA,GAAuB;AAC3B,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,MAAA,CAAO,IAAA,IAAQ,IAAA;AACjC,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,MAAA,CAAO,IAAA,IAAQ,WAAA;AAEjC,IAAA,MAAM,SAAS,OAAA,CAAQ;AAAA,MACrB,MAAA,EAAQ,KAAA;AAAA,MACR,SAAA,EAAW;AAAA,KACZ,CAAA;AAED,IAAA,MAAA,CAAO,OAAA,CAAQ,WAAA,EAAa,OAAO,OAAA,EAAS,KAAA,KAAU;AACpD,MAAA,MAAM,SAAA,GAAa,OAAA,CAAQ,OAAA,CAAQ,cAAc,KAA4B,UAAA,EAAW;AACxF,MAAA,MAAM,OAAA,GAAW,OAAA,CAAQ,OAAA,CAAQ,YAAY,KAA4B,UAAA,EAAW;AAEpF,MAAA,OAAA,CAAQ,EAAA,GAAK,SAAA;AACb,MAAA,KAAA,CAAM,MAAA,CAAO,gBAAgB,SAAS,CAAA;AACtC,MAAA,KAAA,CAAM,MAAA,CAAO,cAAc,OAAO,CAAA;AAElC,MAAA,OAAA,CAAQ,QAAA,GAAW,sBAAA,CAAuB,IAAA,CAAK,MAAA,EAAQ;AAAA,QACrD,SAAA,EAAW,cAAA;AAAA,QACX,UAAA,EAAY,cAAA;AAAA,QACZ,KAAA,EAAO,cAAA;AAAA,QACP,OAAA,EAAS,SAAA;AAAA,QACT,SAAA;AAAA,QACA,OAAA;AAAA,QACA,QAAQ,OAAA,CAAQ,MAAA;AAAA,QAChB,KAAK,OAAA,CAAQ,GAAA;AAAA,QACb,SAAA,EAAW;AAAA,OACZ,CAAA;AACD,MAAA,OAAA,CAAQ,QAAA,CAAS,IAAA,CAAK,CAAA,OAAA,EAAK,OAAA,CAAQ,MAAA,CAAO,aAAa,CAAA,CAAA,EAAI,OAAA,CAAQ,GAAG,CAAA,CAAE,CAAA;AAExE,MAAA,IAAI,OAAA,CAAQ,WAAW,SAAA,EAAW;AAChC,QAAA,KAAA,CAAM,IAAA,CAAK,GAAG,CAAA,CAAE,IAAA,EAAK;AAAA,MACvB;AAAA,IACF,CAAC,CAAA;AACD,IAAA,MAAA,CAAO,OAAA,CAAQ,YAAA,EAAc,OAAO,OAAA,EAAS,KAAA,KAAU;AACrD,MAAA,MAAM,SAAS,OAAA,CAAQ,QAAA;AACvB,MAAA,IAAI,CAAC,MAAA,EAAQ;AACX,QAAA;AAAA,MACF;AAEA,MAAA,MAAA,CAAO,IAAA,CAAK,CAAA,OAAA,EAAK,OAAA,CAAQ,MAAA,CAAO,WAAA,EAAa,CAAA,CAAA,EAAI,OAAA,CAAQ,GAAG,CAAA,CAAA,EAAI,KAAA,CAAM,UAAU,CAAA,CAAA,EAAI;AAAA,QAClF,YAAY,KAAA,CAAM;AAAA,OACnB,CAAA;AAAA,IACH,CAAC,CAAA;AACD,IAAA,MAAA,CAAO,OAAA,CAAQ,QAAA,EAAU,OAAO,QAAA,EAAU,OAAO,OAAA,KAAY;AAC3D,MAAA,KAAA,CAAM,MAAA,CAAO,+BAA+B,GAAG,CAAA;AAC/C,MAAA,KAAA,CAAM,MAAA,CAAO,gCAAgC,iCAAiC,CAAA;AAC9E,MAAA,KAAA,CAAM,MAAA,CAAO,gCAAgC,cAAc,CAAA;AAC3D,MAAA,OAAO,OAAA;AAAA,IACT,CAAC,CAAA;AAED,IAAA,MAAM,gBAAgB,MAAA,EAAQ;AAAA,MAC5B,KAAA,EAAO,sBAAA;AAAA,MACP,WAAA,EAAa,4DAAA;AAAA,MACb,OAAA,EAAS,OAAA;AAAA,MACT,OAAA,EAAS,CAAC,EAAE,GAAA,EAAK,CAAA,OAAA,EAAU,IAAI,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA,EAAI,WAAA,EAAa,WAAA,EAAa,CAAA;AAAA,MACrE,EAAA,EAAI;AAAA,KACL,CAAA;AAED,IAAA,IAAA,CAAK,aAAA,CAAc,SAAS,MAAM,CAAA;AAClC,IAAA,IAAA,CAAK,eAAe,MAAM,CAAA;AAC1B,IAAA,IAAA,CAAK,aAAA,CAAc,eAAA,CAAgB,iBAAA,EAAmB,CAAA,EAAG,IAAI,CAAA;AAC7D,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AAEd,IAAA,MAAM,MAAA,CAAO,MAAA,CAAO,gBAAA,CAAiB,IAAA,EAAM,IAAI,CAAC,CAAA;AAAA,EAClD;AAAA,EAEA,MAAM,IAAA,GAAsB;AAC1B,IAAA,MAAM,IAAA,CAAK,OAAO,IAAA,EAAK;AACvB,IAAA,IAAI,KAAK,MAAA,EAAQ;AACf,MAAA,MAAM,IAAA,CAAK,OAAO,KAAA,EAAM;AACxB,MAAA,IAAA,CAAK,MAAA,GAAS,IAAA;AAAA,IAChB;AAAA,EACF;AAAA,EAEA,MAAc,QAAA,GAA0B;AACtC,IAAA,IAAI,KAAK,cAAA,EAAgB;AACvB,MAAA;AAAA,IACF;AACA,IAAA,IAAA,CAAK,cAAA,GAAiB,IAAA;AACtB,IAAA,IAAA,CAAK,MAAA,CAAO,KAAK,+BAA+B,CAAA;AAChD,IAAA,MAAM,KAAK,IAAA,EAAK;AAChB,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AAAA,EAEQ,eAAA,GAAkB;AACxB,IAAA,OAAO,IAAA,CAAK,cAAc,gBAAA,CAAiB,cAAA,EAAgB,MAAM,IAAA,CAAK,MAAA,CAAO,WAAW,CAAA;AAAA,EAC1F;AAAA,EAEQ,cAAA,GAAiB;AACvB,IAAA,OAAO,IAAA,CAAK,cAAc,gBAAA,CAAiB,aAAA,EAAe,MAAM,IAAA,CAAK,MAAA,CAAO,UAAU,CAAA;AAAA,EACxF;AAAA,EAEQ,eAAe,MAAA,EAA+B;AACpD,IAAA,MAAA,CAAO,GAAA,CAAI,SAAA,EAAW,YAAY,IAAA,CAAK,iBAAiB,CAAA;AAExD,IAAA,MAAA,CAAO,GAAA,CAAI,UAAU,YAAY;AAC/B,MAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,eAAA,EAAgB;AAC1C,MAAA,MAAM,QAAA,GAAW,OAAO,MAAA,KAAW,IAAA;AACnC,MAAA,OAAO,0BAAA,CAA2B;AAAA,QAChC,KAAA,EAAO,OAAO,MAAA,KAAW,IAAA;AAAA,QACzB,MAAA,EAAQ,WAAW,UAAA,GAAa,OAAA;AAAA,QAChC,MAAA,EAAQ,QAAA,GAAW,CAAA,aAAA,EAAgB,MAAA,CAAO,MAAM,CAAA,CAAA,GAAK,OAAA;AAAA,QACrD,UAAA,EAAY;AAAA,UACV,WAAA,EAAa;AAAA,YACX,KAAA,EAAO,OAAO,MAAA,KAAW,IAAA;AAAA,YACzB,QAAQ,MAAA,CAAO;AAAA;AACjB;AACF,OACD,CAAA;AAAA,IACH,CAAC,CAAA;AAED,IAAA,MAAA,CAAO,GAAA,CAAI,QAAA,EAAU,YAAY,IAAA,CAAK,gBAAgB,CAAA;AAEtD,IAAA,MAAA,CAAO,GAAA,CAAI,UAAA,EAAY,OAAO,QAAA,EAAU,KAAA,KAAU;AAChD,MAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,eAAA,EAAgB;AAC1C,MAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,cAAA,EAAe;AACxC,MAAA,KAAA,CAAM,MAAA,CAAO,gBAAgB,0CAA0C,CAAA;AACvE,MAAA,OAAO,KAAK,aAAA,CAAc,uBAAA;AAAA,QACxB,qBAAA,CAAsB,OAAO,MAAM,CAAA;AAAA,QACnC,uBAAuB,KAAK;AAAA,OAC9B;AAAA,IACF,CAAC,CAAA;AAED,IAAA,MAAA,CAAO,IAAI,yBAAA,EAA2B,YAAY,IAAA,CAAK,aAAA,CAAc,eAAe,CAAA;AAEpF,IAAA,MAAA,CAAO,GAAA,CAAI,yBAAyB,YAAY;AAC9C,MAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,eAAA,EAAgB;AAC1C,MAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,cAAA,EAAe;AAExC,MAAA,OAAO,IAAA,CAAK,cAAc,WAAA,CAAY;AAAA,QACpC,MAAA,EAAQ,qBAAA,CAAsB,MAAA,CAAO,MAAM,CAAA;AAAA,QAC3C,MAAA,EAAQ,kBAAkB,MAAM,CAAA;AAAA,QAChC,IAAA,EAAM;AAAA,UACJ,qBAAA,EAAuB,SAAA;AAAA,UACvB,aAAA,EAAe,QAAA;AAAA,UACf,cAAc,KAAA,CAAM,YAAA;AAAA,UACpB,WAAW,KAAA,CAAM,SAAA;AAAA,UACjB,SAAS,KAAA,CAAM,OAAA;AAAA,UACf,UAAU,KAAA,CAAM,QAAA;AAAA,UAChB,WAAW,KAAA,CAAM;AAAA;AACnB,OACD,CAAA;AAAA,IACH,CAAC,CAAA;AAED,IAAA,MAAA,CAAO,GAAA,CAAI,aAAA,EAAe,OAAO,OAAA,EAAS,KAAA,KAAU;AAClD,MAAA,MAAM,EAAE,GAAA,EAAI,GAAI,OAAA,CAAQ,MAAA;AACxB,MAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,aAAA,CAAc,gBAAA,CAAiB,WAAA,EAAa,MAAM,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,GAAG,CAAC,CAAA;AAE/F,MAAA,IAAI,UAAU,IAAA,EAAM;AAClB,QAAA,KAAA,CAAM,KAAK,GAAG,CAAA;AACd,QAAA,OAAO,IAAA;AAAA,MACT;AAEA,MAAA,KAAA,CAAM,KAAK,kBAAkB,CAAA;AAC7B,MAAA,OAAO,IAAA,CAAK,UAAU,KAAK,CAAA;AAAA,IAC7B,CAAC,CAAA;AAED,IAAA,MAAA,CAAO,GAAA,CAAI,aAAA,EAAe,OAAO,OAAA,EAAS,KAAA,KAAU;AAClD,MAAA,MAAM,EAAE,GAAA,EAAI,GAAI,OAAA,CAAQ,MAAA;AACxB,MAAA,MAAM,EAAE,KAAA,EAAO,GAAA,EAAI,GAAI,OAAA,CAAQ,IAAA;AAC/B,MAAA,MAAM,IAAA,CAAK,aAAA,CAAc,gBAAA,CAAiB,WAAA,EAAa,MAAM,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,GAAA,EAAK,KAAA,EAAO,GAAG,CAAC,CAAA;AAC7F,MAAA,KAAA,CAAM,KAAK,GAAG,CAAA;AACd,MAAA,OAAO,IAAA;AAAA,IACT,CAAC,CAAA;AAED,IAAA,MAAA,CAAO,GAAA,CAAI,uBAAA,EAAyB,OAAO,OAAA,EAAS,KAAA,KAAU;AAC5D,MAAA,MAAM,EAAE,GAAA,EAAI,GAAI,OAAA,CAAQ,MAAA;AACxB,MAAA,MAAM,EAAE,KAAA,EAAO,GAAA,EAAI,GAAI,OAAA,CAAQ,IAAA;AAC/B,MAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,aAAA,CAAc,gBAAA,CAAiB,sBAAA,EAAwB,MAAM,IAAA,CAAK,MAAA,CAAO,cAAA,CAAe,GAAA,EAAK,KAAA,EAAO,GAAG,CAAC,CAAA;AACpI,MAAA,KAAA,CAAM,IAAA,CAAK,QAAA,GAAW,GAAA,GAAM,GAAG,CAAA;AAC/B,MAAA,OAAO,IAAA;AAAA,IACT,CAAC,CAAA;AAED,IAAA,MAAA,CAAO,GAAA,CAAI,kBAAA,EAAoB,OAAO,OAAA,EAAS,KAAA,KAAU;AACvD,MAAA,MAAM,EAAE,GAAA,EAAI,GAAI,OAAA,CAAQ,MAAA;AACxB,MAAA,MAAM,EAAE,KAAA,EAAO,MAAA,EAAO,GAAI,OAAA,CAAQ,IAAA;AAClC,MAAA,MAAM,IAAA,CAAK,aAAA,CAAc,gBAAA,CAAiB,YAAA,EAAc,MAAM,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,GAAA,EAAK,KAAA,EAAO,MAAM,CAAC,CAAA;AAClG,MAAA,KAAA,CAAM,KAAK,GAAG,CAAA;AACd,MAAA,OAAO,IAAA;AAAA,IACT,CAAC,CAAA;AAED,IAAA,MAAA,CAAO,MAAA,CAAO,kBAAA,EAAoB,OAAO,OAAA,EAAS,KAAA,KAAU;AAC1D,MAAA,MAAM,EAAE,GAAA,EAAI,GAAI,OAAA,CAAQ,MAAA;AACxB,MAAA,MAAM,EAAE,MAAA,EAAO,GAAI,OAAA,CAAQ,IAAA;AAC3B,MAAA,MAAM,IAAA,CAAK,aAAA,CAAc,gBAAA,CAAiB,YAAA,EAAc,MAAM,KAAK,MAAA,CAAO,IAAA,CAAK,GAAA,EAAK,MAAM,CAAC,CAAA;AAC3F,MAAA,KAAA,CAAM,KAAK,GAAG,CAAA;AACd,MAAA,OAAO,IAAA;AAAA,IACT,CAAC,CAAA;AAED,IAAA,MAAA,CAAO,GAAA,CAAI,mBAAA,EAAqB,OAAO,OAAA,EAAS,KAAA,KAAU;AACxD,MAAA,MAAM,EAAE,GAAA,EAAI,GAAI,OAAA,CAAQ,MAAA;AACxB,MAAA,MAAM,QAAQ,OAAA,CAAQ,KAAA;AACtB,MAAA,MAAM,UAAU,MAAM,IAAA,CAAK,cAAc,gBAAA,CAAiB,qBAAA,EAAuB,MAAM,IAAA,CAAK,MAAA,CAAO,cAAc,GAAA,EAAK,MAAA,CAAO,MAAM,GAAG,CAAA,EAAG,OAAO,KAAA,CAAM,GAAG,CAAC,CAAC,CAAA;AAC3J,MAAA,KAAA,CAAM,KAAK,kBAAkB,CAAA;AAC7B,MAAA,OAAO,OAAA;AAAA,IACT,CAAC,CAAA;AAED,IAAA,MAAA,CAAO,MAAA,CAAO,aAAA,EAAe,OAAO,OAAA,EAAS,KAAA,KAAU;AACrD,MAAA,MAAM,EAAE,GAAA,EAAI,GAAI,OAAA,CAAQ,MAAA;AACxB,MAAA,MAAM,IAAA,CAAK,cAAc,gBAAA,CAAiB,cAAA,EAAgB,MAAM,IAAA,CAAK,MAAA,CAAO,MAAA,CAAO,GAAG,CAAC,CAAA;AACvF,MAAA,KAAA,CAAM,KAAK,GAAG,CAAA;AACd,MAAA,OAAO,IAAA;AAAA,IACT,CAAC,CAAA;AAED,IAAA,MAAA,CAAO,IAAA,CAAK,cAAA,EAAgB,OAAO,OAAA,EAAS,KAAA,KAAU;AACpD,MAAA,MAAM,OAAA,GAAW,QAAQ,KAAA,CAA+B,OAAA;AACxD,MAAA,MAAM,IAAA,CAAK,cAAc,gBAAA,CAAiB,aAAA,EAAe,MAAM,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,OAAO,CAAC,CAAA;AACzF,MAAA,KAAA,CAAM,KAAK,GAAG,CAAA;AACd,MAAA,OAAO,IAAA;AAAA,IACT,CAAC,CAAA;AAAA,EACH;AACF;AAEA,SAAS,sBAAsB,MAAA,EAAkE;AAC/F,EAAA,IAAI,WAAW,IAAA,EAAM;AACnB,IAAA,OAAO,SAAA;AAAA,EACT;AACA,EAAA,IAAI,WAAW,UAAA,EAAY;AACzB,IAAA,OAAO,UAAA;AAAA,EACT;AACA,EAAA,OAAO,WAAA;AACT;AAEA,SAAS,kBAAkB,MAAA,EAAqF;AAC9G,EAAA,OAAO;AAAA,IACL;AAAA,MACE,EAAA,EAAI,cAAA;AAAA,MACJ,MAAA,EAAQ,OAAO,MAAA,KAAW,IAAA,GAAO,OAAO,MAAA,CAAO,MAAA,KAAW,aAAa,MAAA,GAAS,OAAA;AAAA,MAChF,OAAA,EAAS,CAAA,iBAAA,EAAoB,MAAA,CAAO,MAAM,CAAA;AAAA;AAC5C,GACF;AACF;AAEA,SAAS,uBAAuB,KAAA,EAAuE;AACrG,EAAA,OAAO;AAAA,IACL,4EAAA;AAAA,IACA,yCAAA;AAAA,IACA,UAAA,CAAW,4BAAA,EAA8B,KAAA,CAAM,YAAY,CAAA;AAAA,IAC3D,6EAAA;AAAA,IACA,sCAAA;AAAA,IACA,UAAA,CAAW,yBAAA,EAA2B,KAAA,CAAM,SAAS,CAAA;AAAA,IACrD,4EAAA;AAAA,IACA,2CAAA;AAAA,IACA,UAAA,CAAW,8BAAA,EAAgC,KAAA,CAAM,SAAS;AAAA,GAC5D;AACF;ACvVA,eAAsB,SAAA,CAAU,IAAA,GAAe,OAAA,CAAQ,GAAA,EAAI,EAAkB;AAC3E,EAAA,MAAM,SAAA;AAAA,IACJ;AAAA,MACE,KAAA,EAAO,cAAA;AAAA,MACP,WAAA,EAAa,IAAA;AAAA,MACb,UAAA,EAAY,sBAAA;AAAA,MACZ,WAAA,EAAa,WAAA;AAAA,MACb,UAAA,EAAY,sBAAA;AAAA,MACZ,MAAM,KAAA,CAAM,EAAE,QAAA,EAAU,IAAA,EAAM,MAAK,EAAG;AACpC,QAAA,MAAM,MAAA,GAAS,IAAI,iBAAA,CAAkB,EAAE,MAAM,IAAA,EAAM,MAAA,EAAQ,QAAA,CAAS,MAAA,EAAQ,CAAA;AAC5E,QAAA,MAAM,OAAO,KAAA,EAAM;AACnB,QAAA,OAAO,MAAM,OAAO,IAAA,EAAK;AAAA,MAC3B;AAAA,KACF;AAAA,IACA,CAAC,KAAA,EAAO,QAAA,KACN,sBAAA,CAAuB,EAAE,OAAO,QAAA,EAAU,YAAA,EAAc,gBAAA,EAAiB,EAAG;AAAA,GAChF;AACF","file":"index.js","sourcesContent":["import Fastify, { type FastifyInstance } from 'fastify';\nimport { InMemoryStateBroker } from '@kb-labs/core-state-broker';\nimport type { ILogger } from '@kb-labs/core-platform';\nimport {\n createCorrelatedLogger,\n HttpObservabilityCollector,\n createServiceReadyResponse,\n getListenOptions,\n metricLine,\n registerOpenAPI,\n} from '@kb-labs/shared-http';\nimport type { ObservabilityCheck, ServiceHealthStatus } from '@kb-labs/core-contracts';\nimport { randomUUID } from 'node:crypto';\n\nexport interface StateDaemonConfig {\n port?: number;\n host?: string;\n logger?: ILogger;\n}\n\nfunction createFallbackLogger(): ILogger {\n const bindings: Record<string, unknown> = {};\n\n const formatMeta = (meta?: Record<string, unknown>) => {\n const combined = { ...bindings, ...(meta ?? {}) };\n return Object.keys(combined).length > 0 ? ` ${JSON.stringify(combined)}` : '';\n };\n\n return {\n info(message: string, meta?: Record<string, unknown>) {\n console.log(`[INFO] ${message}${formatMeta(meta)}`);\n },\n warn(message: string, meta?: Record<string, unknown>) {\n console.warn(`[WARN] ${message}${formatMeta(meta)}`);\n },\n error(message: string, error?: Error, meta?: Record<string, unknown>) {\n const merged = error\n ? { ...(meta ?? {}), error: { message: error.message, stack: error.stack } }\n : meta;\n console.error(`[ERROR] ${message}${formatMeta(merged)}`);\n },\n fatal(message: string, error?: Error, meta?: Record<string, unknown>) {\n const merged = error\n ? { ...(meta ?? {}), error: { message: error.message, stack: error.stack } }\n : meta;\n console.error(`[FATAL] ${message}${formatMeta(merged)}`);\n },\n debug(message: string, meta?: Record<string, unknown>) {\n console.debug(`[DEBUG] ${message}${formatMeta(meta)}`);\n },\n trace(message: string, meta?: Record<string, unknown>) {\n console.debug(`[TRACE] ${message}${formatMeta(meta)}`);\n },\n child(childBindings: Record<string, unknown>) {\n const childLogger = createFallbackLogger();\n return {\n ...childLogger,\n info(message: string, meta?: Record<string, unknown>) {\n console.log(`[INFO] ${message}${formatMeta({ ...childBindings, ...(meta ?? {}) })}`);\n },\n warn(message: string, meta?: Record<string, unknown>) {\n console.warn(`[WARN] ${message}${formatMeta({ ...childBindings, ...(meta ?? {}) })}`);\n },\n error(message: string, error?: Error, meta?: Record<string, unknown>) {\n const merged = error\n ? { ...childBindings, ...(meta ?? {}), error: { message: error.message, stack: error.stack } }\n : { ...childBindings, ...(meta ?? {}) };\n console.error(`[ERROR] ${message}${formatMeta(merged)}`);\n },\n fatal(message: string, error?: Error, meta?: Record<string, unknown>) {\n const merged = error\n ? { ...childBindings, ...(meta ?? {}), error: { message: error.message, stack: error.stack } }\n : { ...childBindings, ...(meta ?? {}) };\n console.error(`[FATAL] ${message}${formatMeta(merged)}`);\n },\n debug(message: string, meta?: Record<string, unknown>) {\n console.debug(`[DEBUG] ${message}${formatMeta({ ...childBindings, ...(meta ?? {}) })}`);\n },\n trace(message: string, meta?: Record<string, unknown>) {\n console.debug(`[TRACE] ${message}${formatMeta({ ...childBindings, ...(meta ?? {}) })}`);\n },\n };\n },\n };\n}\n\nexport class StateDaemonServer {\n private readonly broker = new InMemoryStateBroker();\n private readonly observability = new HttpObservabilityCollector({\n serviceId: 'state-daemon',\n serviceType: 'state-daemon',\n version: '1.2.0',\n logsSource: 'state-daemon',\n });\n private readonly logger: ILogger;\n private server: FastifyInstance | null = null;\n private isShuttingDown = false;\n\n constructor(private readonly config: StateDaemonConfig = {}) {\n this.logger = config.logger ?? createFallbackLogger();\n }\n\n async start(): Promise<void> {\n const port = this.config.port ?? 7777;\n const host = this.config.host ?? 'localhost';\n\n const server = Fastify({\n logger: false,\n bodyLimit: 1048576,\n });\n\n server.addHook('onRequest', async (request, reply) => {\n const requestId = (request.headers['x-request-id'] as string | undefined) || randomUUID();\n const traceId = (request.headers['x-trace-id'] as string | undefined) || randomUUID();\n\n request.id = requestId;\n reply.header('X-Request-Id', requestId);\n reply.header('X-Trace-Id', traceId);\n\n request.kbLogger = createCorrelatedLogger(this.logger, {\n serviceId: 'state-daemon',\n logsSource: 'state-daemon',\n layer: 'state-daemon',\n service: 'request',\n requestId,\n traceId,\n method: request.method,\n url: request.url,\n operation: 'http.request',\n });\n request.kbLogger.info(`→ ${request.method.toUpperCase()} ${request.url}`);\n\n if (request.method === 'OPTIONS') {\n reply.code(204).send();\n }\n });\n server.addHook('onResponse', async (request, reply) => {\n const logger = request.kbLogger;\n if (!logger) {\n return;\n }\n\n logger.info(`✓ ${request.method.toUpperCase()} ${request.url} ${reply.statusCode}`, {\n statusCode: reply.statusCode,\n });\n });\n server.addHook('onSend', async (_request, reply, payload) => {\n reply.header('Access-Control-Allow-Origin', '*');\n reply.header('Access-Control-Allow-Methods', 'GET, PUT, DELETE, POST, OPTIONS');\n reply.header('Access-Control-Allow-Headers', 'Content-Type');\n return payload;\n });\n\n await registerOpenAPI(server, {\n title: 'KB Labs State Daemon',\n description: 'State broker service for persistent cross-invocation state',\n version: '1.2.0',\n servers: [{ url: `http://${host}:${port}`, description: 'Local dev' }],\n ui: false,\n });\n\n this.observability.register(server);\n this.registerRoutes(server);\n this.observability.recordOperation('state.bootstrap', 0, 'ok');\n this.server = server;\n\n await server.listen(getListenOptions(port, host));\n }\n\n async stop(): Promise<void> {\n await this.broker.stop();\n if (this.server) {\n await this.server.close();\n this.server = null;\n }\n }\n\n private async shutdown(): Promise<void> {\n if (this.isShuttingDown) {\n return;\n }\n this.isShuttingDown = true;\n this.logger.info('Shutting down state daemon...');\n await this.stop();\n process.exit(0);\n }\n\n private getBrokerHealth() {\n return this.observability.observeOperation('state.health', () => this.broker.getHealth());\n }\n\n private getBrokerStats() {\n return this.observability.observeOperation('state.stats', () => this.broker.getStats());\n }\n\n private registerRoutes(server: FastifyInstance): void {\n server.get('/health', async () => this.getBrokerHealth());\n\n server.get('/ready', async () => {\n const health = await this.getBrokerHealth();\n const degraded = health.status !== 'ok';\n return createServiceReadyResponse({\n ready: health.status === 'ok',\n status: degraded ? 'degraded' : 'ready',\n reason: degraded ? `state_broker_${health.status}` : 'ready',\n components: {\n stateBroker: {\n ready: health.status === 'ok',\n status: health.status,\n },\n },\n });\n });\n\n server.get('/stats', async () => this.getBrokerStats());\n\n server.get('/metrics', async (_request, reply) => {\n const health = await this.getBrokerHealth();\n const stats = await this.getBrokerStats();\n reply.header('Content-Type', 'text/plain; version=0.0.4; charset=utf-8');\n return this.observability.renderPrometheusMetrics(\n mapBrokerHealthStatus(health.status),\n buildBrokerMetricLines(stats),\n );\n });\n\n server.get('/observability/describe', async () => this.observability.buildDescribe());\n\n server.get('/observability/health', async () => {\n const health = await this.getBrokerHealth();\n const stats = await this.getBrokerStats();\n\n return this.observability.buildHealth({\n status: mapBrokerHealthStatus(health.status),\n checks: buildBrokerChecks(health),\n meta: {\n serviceHealthEndpoint: '/health',\n statsEndpoint: '/stats',\n totalEntries: stats.totalEntries,\n totalSize: stats.totalSize,\n hitRate: stats.hitRate,\n missRate: stats.missRate,\n evictions: stats.evictions,\n },\n });\n });\n\n server.get('/state/:key', async (request, reply) => {\n const { key } = request.params as { key: string };\n const value = await this.observability.observeOperation('state.get', () => this.broker.get(key));\n\n if (value === null) {\n reply.code(404);\n return null;\n }\n\n reply.type('application/json');\n return JSON.stringify(value);\n });\n\n server.put('/state/:key', async (request, reply) => {\n const { key } = request.params as { key: string };\n const { value, ttl } = request.body as { value: unknown; ttl?: number };\n await this.observability.observeOperation('state.set', () => this.broker.set(key, value, ttl));\n reply.code(204);\n return null;\n });\n\n server.put('/state/:key/if-absent', async (request, reply) => {\n const { key } = request.params as { key: string };\n const { value, ttl } = request.body as { value: unknown; ttl?: number };\n const inserted = await this.observability.observeOperation('state.setIfNotExists', () => this.broker.setIfNotExists(key, value, ttl));\n reply.code(inserted ? 204 : 409);\n return null;\n });\n\n server.put('/state/:key/zset', async (request, reply) => {\n const { key } = request.params as { key: string };\n const { score, member } = request.body as { score: number; member: string };\n await this.observability.observeOperation('state.zadd', () => this.broker.zadd(key, score, member));\n reply.code(204);\n return null;\n });\n\n server.delete('/state/:key/zset', async (request, reply) => {\n const { key } = request.params as { key: string };\n const { member } = request.body as { member: string };\n await this.observability.observeOperation('state.zrem', () => this.broker.zrem(key, member));\n reply.code(204);\n return null;\n });\n\n server.get('/state/:key/range', async (request, reply) => {\n const { key } = request.params as { key: string };\n const query = request.query as { min?: string; max?: string };\n const members = await this.observability.observeOperation('state.zrangebyscore', () => this.broker.zrangebyscore(key, Number(query.min), Number(query.max)));\n reply.type('application/json');\n return members;\n });\n\n server.delete('/state/:key', async (request, reply) => {\n const { key } = request.params as { key: string };\n await this.observability.observeOperation('state.delete', () => this.broker.delete(key));\n reply.code(204);\n return null;\n });\n\n server.post('/state/clear', async (request, reply) => {\n const pattern = (request.query as { pattern?: string }).pattern;\n await this.observability.observeOperation('state.clear', () => this.broker.clear(pattern));\n reply.code(204);\n return null;\n });\n }\n}\n\nfunction mapBrokerHealthStatus(status: 'ok' | 'degraded' | 'shutting_down'): ServiceHealthStatus {\n if (status === 'ok') {\n return 'healthy';\n }\n if (status === 'degraded') {\n return 'degraded';\n }\n return 'unhealthy';\n}\n\nfunction buildBrokerChecks(health: Awaited<ReturnType<InMemoryStateBroker['getHealth']>>): ObservabilityCheck[] {\n return [\n {\n id: 'state-broker',\n status: health.status === 'ok' ? 'ok' : health.status === 'degraded' ? 'warn' : 'error',\n message: `Broker status is ${health.status}`,\n },\n ];\n}\n\nfunction buildBrokerMetricLines(stats: Awaited<ReturnType<InMemoryStateBroker['getStats']>>): string[] {\n return [\n '# HELP state_broker_entries_total Total entries stored by the state broker',\n '# TYPE state_broker_entries_total gauge',\n metricLine('state_broker_entries_total', stats.totalEntries),\n '# HELP state_broker_size_bytes Estimated total size of state broker entries',\n '# TYPE state_broker_size_bytes gauge',\n metricLine('state_broker_size_bytes', stats.totalSize),\n '# HELP state_broker_evictions_total Number of evicted state broker entries',\n '# TYPE state_broker_evictions_total gauge',\n metricLine('state_broker_evictions_total', stats.evictions),\n ];\n}\n","import { createServiceBootstrap } from '@kb-labs/core-runtime';\nimport { makeAssemblyHook } from '@kb-labs/plugin-runtime';\nimport { runDaemon } from '@kb-labs/shared-daemon';\nimport { StateDaemonServer } from './server.js';\n\nexport async function bootstrap(_cwd: string = process.cwd()): Promise<void> {\n await runDaemon(\n {\n appId: 'state-daemon',\n defaultPort: 7777,\n portEnvVar: 'KB_STATE_DAEMON_PORT',\n defaultHost: 'localhost',\n hostEnvVar: 'KB_STATE_DAEMON_HOST',\n async setup({ platform, port, host }) {\n const server = new StateDaemonServer({ port, host, logger: platform.logger });\n await server.start();\n return () => server.stop();\n },\n },\n (appId, repoRoot) =>\n createServiceBootstrap({ appId, repoRoot, assemblyHook: makeAssemblyHook() }),\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/server.ts","../src/bootstrap.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import Fastify, { type FastifyInstance } from \"fastify\";\nimport { InMemoryStateBroker } from \"@kb-labs/core-state-broker\";\nimport {\n createContextLogger,\n type IContextLogger,\n type ILogger,\n} from \"@kb-labs/core-platform\";\nimport { ConsoleLogger } from \"@kb-labs/core-platform/inmemory\";\nimport {\n createHttpLogger,\n HttpObservabilityCollector,\n createServiceReadyResponse,\n getListenOptions,\n metricLine,\n registerOpenAPI,\n} from \"@kb-labs/shared-http\";\nimport type {\n ObservabilityCheck,\n ServiceHealthStatus,\n} from \"@kb-labs/core-contracts\";\nimport { randomUUID } from \"node:crypto\";\n\nexport interface StateDaemonConfig {\n port?: number;\n host?: string;\n logger?: ILogger;\n}\n\nfunction createFallbackLogger(): IContextLogger {\n return createContextLogger(new ConsoleLogger(), {\n applicationId: \"kb-labs\",\n serviceId: \"state-daemon\",\n instanceId: `local:${process.pid}`,\n layer: \"service\",\n });\n}\n\nexport class StateDaemonServer {\n private readonly broker = new InMemoryStateBroker();\n private readonly observability = new HttpObservabilityCollector({\n serviceId: \"state-daemon\",\n serviceType: \"state-daemon\",\n version: \"1.2.0\",\n logsSource: \"state-daemon\",\n });\n private readonly logger: IContextLogger;\n private server: FastifyInstance | null = null;\n\n constructor(private readonly config: StateDaemonConfig = {}) {\n this.logger = createContextLogger(config.logger ?? createFallbackLogger(), {\n applicationId: \"kb-labs\",\n serviceId: \"state-daemon\",\n instanceId: `local:${process.pid}`,\n layer: \"service\",\n });\n }\n\n async start(): Promise<void> {\n const port = this.config.port ?? 7777;\n const host = this.config.host ?? \"localhost\";\n\n const server = Fastify({\n logger: false,\n bodyLimit: 1048576,\n });\n\n server.addHook(\"onRequest\", async (request, reply) => {\n const requestId =\n (request.headers[\"x-request-id\"] as string | undefined) || randomUUID();\n const traceId =\n (request.headers[\"x-trace-id\"] as string | undefined) || randomUUID();\n\n request.id = requestId;\n reply.header(\"X-Request-Id\", requestId);\n reply.header(\"X-Trace-Id\", traceId);\n\n request.kbLogger = createHttpLogger(this.logger, {\n serviceId: \"state-daemon\",\n layer: \"service\",\n component: \"http-request\",\n requestId,\n traceId,\n method: request.method,\n url: request.url,\n operation: \"http.request\",\n });\n request.kbLogger.debug(\"HTTP request started\");\n\n if (request.method === \"OPTIONS\") {\n reply.code(204).send();\n }\n });\n server.addHook(\"onResponse\", async (request, reply) => {\n const logger = request.kbLogger;\n if (!logger) {\n return;\n }\n\n logger.info(\"HTTP request completed\", {\n \"http.status_code\": reply.statusCode,\n });\n });\n server.addHook(\"onSend\", async (_request, reply, payload) => {\n reply.header(\"Access-Control-Allow-Origin\", \"*\");\n reply.header(\n \"Access-Control-Allow-Methods\",\n \"GET, PUT, DELETE, POST, OPTIONS\",\n );\n reply.header(\"Access-Control-Allow-Headers\", \"Content-Type\");\n return payload;\n });\n\n await registerOpenAPI(server, {\n title: \"KB Labs State Daemon\",\n description: \"State broker service for persistent cross-invocation state\",\n version: \"1.2.0\",\n servers: [{ url: `http://${host}:${port}`, description: \"Local dev\" }],\n ui: false,\n });\n\n this.observability.register(server);\n this.registerRoutes(server);\n this.observability.recordOperation(\"state.bootstrap\", 0, \"ok\");\n this.server = server;\n\n await server.listen(getListenOptions(port, host));\n }\n\n async stop(): Promise<void> {\n await this.broker.stop();\n if (this.server) {\n await this.server.close();\n this.server = null;\n }\n }\n\n private getBrokerHealth() {\n return this.observability.observeOperation(\"state.health\", () =>\n this.broker.getHealth(),\n );\n }\n\n private getBrokerStats() {\n return this.observability.observeOperation(\"state.stats\", () =>\n this.broker.getStats(),\n );\n }\n\n private registerRoutes(server: FastifyInstance): void {\n server.get(\"/health\", async () => this.getBrokerHealth());\n\n server.get(\"/ready\", async () => {\n const health = await this.getBrokerHealth();\n const degraded = health.status !== \"ok\";\n return createServiceReadyResponse({\n ready: health.status === \"ok\",\n status: degraded ? \"degraded\" : \"ready\",\n reason: degraded ? `state_broker_${health.status}` : \"ready\",\n components: {\n stateBroker: {\n ready: health.status === \"ok\",\n status: health.status,\n },\n },\n });\n });\n\n server.get(\"/stats\", async () => this.getBrokerStats());\n\n server.get(\"/metrics\", async (_request, reply) => {\n const health = await this.getBrokerHealth();\n const stats = await this.getBrokerStats();\n reply.header(\"Content-Type\", \"text/plain; version=0.0.4; charset=utf-8\");\n return this.observability.renderPrometheusMetrics(\n mapBrokerHealthStatus(health.status),\n buildBrokerMetricLines(stats),\n );\n });\n\n server.get(\"/observability/describe\", async () =>\n this.observability.buildDescribe(),\n );\n\n server.get(\"/observability/health\", async () => {\n const health = await this.getBrokerHealth();\n const stats = await this.getBrokerStats();\n\n return this.observability.buildHealth({\n status: mapBrokerHealthStatus(health.status),\n checks: buildBrokerChecks(health),\n meta: {\n serviceHealthEndpoint: \"/health\",\n statsEndpoint: \"/stats\",\n totalEntries: stats.totalEntries,\n totalSize: stats.totalSize,\n hitRate: stats.hitRate,\n missRate: stats.missRate,\n evictions: stats.evictions,\n },\n });\n });\n\n server.get(\"/state/:key\", async (request, reply) => {\n const { key } = request.params as { key: string };\n const value = await this.observability.observeOperation(\"state.get\", () =>\n this.broker.get(key),\n );\n\n if (value === null) {\n reply.code(404);\n return null;\n }\n\n reply.type(\"application/json\");\n return JSON.stringify(value);\n });\n\n server.put(\"/state/:key\", async (request, reply) => {\n const { key } = request.params as { key: string };\n const { value, ttl } = request.body as { value: unknown; ttl?: number };\n await this.observability.observeOperation(\"state.set\", () =>\n this.broker.set(key, value, ttl),\n );\n reply.code(204);\n return null;\n });\n\n server.put(\"/state/:key/if-absent\", async (request, reply) => {\n const { key } = request.params as { key: string };\n const { value, ttl } = request.body as { value: unknown; ttl?: number };\n const inserted = await this.observability.observeOperation(\n \"state.setIfNotExists\",\n () => this.broker.setIfNotExists(key, value, ttl),\n );\n reply.code(inserted ? 204 : 409);\n return null;\n });\n\n server.put(\"/state/:key/zset\", async (request, reply) => {\n const { key } = request.params as { key: string };\n const { score, member } = request.body as {\n score: number;\n member: string;\n };\n await this.observability.observeOperation(\"state.zadd\", () =>\n this.broker.zadd(key, score, member),\n );\n reply.code(204);\n return null;\n });\n\n server.delete(\"/state/:key/zset\", async (request, reply) => {\n const { key } = request.params as { key: string };\n const { member } = request.body as { member: string };\n await this.observability.observeOperation(\"state.zrem\", () =>\n this.broker.zrem(key, member),\n );\n reply.code(204);\n return null;\n });\n\n server.get(\"/state/:key/range\", async (request, reply) => {\n const { key } = request.params as { key: string };\n const query = request.query as { min?: string; max?: string };\n const members = await this.observability.observeOperation(\n \"state.zrangebyscore\",\n () =>\n this.broker.zrangebyscore(key, Number(query.min), Number(query.max)),\n );\n reply.type(\"application/json\");\n return members;\n });\n\n server.delete(\"/state/:key\", async (request, reply) => {\n const { key } = request.params as { key: string };\n await this.observability.observeOperation(\"state.delete\", () =>\n this.broker.delete(key),\n );\n reply.code(204);\n return null;\n });\n\n server.post(\"/state/clear\", async (request, reply) => {\n const pattern = (request.query as { pattern?: string }).pattern;\n await this.observability.observeOperation(\"state.clear\", () =>\n this.broker.clear(pattern),\n );\n reply.code(204);\n return null;\n });\n }\n}\n\nfunction mapBrokerHealthStatus(\n status: \"ok\" | \"degraded\" | \"shutting_down\",\n): ServiceHealthStatus {\n if (status === \"ok\") {\n return \"healthy\";\n }\n if (status === \"degraded\") {\n return \"degraded\";\n }\n return \"unhealthy\";\n}\n\nfunction buildBrokerChecks(\n health: Awaited<ReturnType<InMemoryStateBroker[\"getHealth\"]>>,\n): ObservabilityCheck[] {\n return [\n {\n id: \"state-broker\",\n status:\n health.status === \"ok\"\n ? \"ok\"\n : health.status === \"degraded\"\n ? \"warn\"\n : \"error\",\n message: `Broker status is ${health.status}`,\n },\n ];\n}\n\nfunction buildBrokerMetricLines(\n stats: Awaited<ReturnType<InMemoryStateBroker[\"getStats\"]>>,\n): string[] {\n return [\n \"# HELP state_broker_entries_total Total entries stored by the state broker\",\n \"# TYPE state_broker_entries_total gauge\",\n metricLine(\"state_broker_entries_total\", stats.totalEntries),\n \"# HELP state_broker_size_bytes Estimated total size of state broker entries\",\n \"# TYPE state_broker_size_bytes gauge\",\n metricLine(\"state_broker_size_bytes\", stats.totalSize),\n \"# HELP state_broker_evictions_total Number of evicted state broker entries\",\n \"# TYPE state_broker_evictions_total gauge\",\n metricLine(\"state_broker_evictions_total\", stats.evictions),\n ];\n}\n","import { makeAssemblyHook } from \"@kb-labs/plugin-runtime\";\nimport { runService } from \"@kb-labs/shared-daemon\";\nimport { StateDaemonServer } from \"./server.js\";\n\nexport async function bootstrap(_cwd: string = process.cwd()): Promise<void> {\n await runService({\n appId: \"state-daemon\",\n startDir: _cwd,\n defaultPort: 7777,\n portEnvVar: \"KB_STATE_DAEMON_PORT\",\n defaultHost: \"localhost\",\n hostEnvVar: \"KB_STATE_DAEMON_HOST\",\n platform: {\n assemblyHook: makeAssemblyHook(),\n },\n async setup({ port, host, logger }) {\n const server = new StateDaemonServer({\n port,\n host,\n logger,\n });\n await server.start();\n return () => server.stop();\n },\n });\n}\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kb-labs/core-state-daemon",
3
3
  "description": "State daemon server for persistent cross-invocation state",
4
- "version": "2.112.0",
4
+ "version": "2.114.0",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
@@ -31,15 +31,15 @@
31
31
  "dependencies": {
32
32
  "@fastify/swagger": ">=9.5.1",
33
33
  "@fastify/swagger-ui": "^5.2.0",
34
- "@kb-labs/core-contracts": "^2.112.0",
35
- "@kb-labs/core-platform": "^2.112.0",
36
- "@kb-labs/core-runtime": "^2.112.0",
37
- "@kb-labs/plugin-runtime": "^2.112.0",
38
- "@kb-labs/shared-daemon": "^2.112.0",
39
- "@kb-labs/core-state-broker": "^2.112.0",
40
- "@kb-labs/core-sys": "^2.112.0",
41
- "@kb-labs/plugin-contracts": "^2.112.0",
42
- "@kb-labs/shared-http": "^2.112.0",
34
+ "@kb-labs/core-contracts": "^2.114.0",
35
+ "@kb-labs/core-platform": "^2.114.0",
36
+ "@kb-labs/core-runtime": "^2.114.0",
37
+ "@kb-labs/plugin-runtime": "^2.114.0",
38
+ "@kb-labs/shared-daemon": "^2.114.0",
39
+ "@kb-labs/core-state-broker": "^2.114.0",
40
+ "@kb-labs/core-sys": "^2.114.0",
41
+ "@kb-labs/plugin-contracts": "^2.114.0",
42
+ "@kb-labs/shared-http": "^2.114.0",
43
43
  "fastify": "^5.8.5",
44
44
  "fastify-type-provider-zod": "^4.0.2"
45
45
  },