@donkeylabs/server 2.0.21 → 2.0.22

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/src/index.ts CHANGED
@@ -99,6 +99,16 @@ export {
99
99
  type ErrorFactories,
100
100
  } from "./core/index";
101
101
 
102
+ // Logs (persistent logging)
103
+ export {
104
+ type Logs,
105
+ type LogSource,
106
+ type PersistentLogEntry,
107
+ type LogsQueryFilters,
108
+ type LogsConfig,
109
+ type LogsRetentionConfig,
110
+ } from "./core/logs";
111
+
102
112
  // Workflows (step functions)
103
113
  export {
104
114
  workflow,
package/src/server.ts CHANGED
@@ -19,12 +19,16 @@ import {
19
19
  createAudit,
20
20
  createWebSocket,
21
21
  createStorage,
22
+ createLogs,
22
23
  extractClientIP,
23
24
  HttpError,
24
25
  KyselyJobAdapter,
25
26
  KyselyProcessAdapter,
26
27
  KyselyWorkflowAdapter,
27
28
  KyselyAuditAdapter,
29
+ KyselyLogsAdapter,
30
+ PersistentTransport,
31
+ ConsoleTransport,
28
32
  type LoggerConfig,
29
33
  type CacheConfig,
30
34
  type EventsConfig,
@@ -38,6 +42,7 @@ import {
38
42
  type AuditConfig,
39
43
  type WebSocketConfig,
40
44
  type StorageConfig,
45
+ type LogsConfig,
41
46
  } from "./core/index";
42
47
  import type { AdminConfig } from "./admin";
43
48
  import { zodSchemaToTs } from "./generator/zod-to-ts";
@@ -80,6 +85,7 @@ export interface ServerConfig {
80
85
  audit?: AuditConfig;
81
86
  websocket?: WebSocketConfig;
82
87
  storage?: StorageConfig;
88
+ logs?: LogsConfig;
83
89
  /**
84
90
  * Admin dashboard configuration.
85
91
  * Automatically enabled in dev mode, disabled in production.
@@ -224,23 +230,52 @@ export class AppServer {
224
230
  const useLegacy = options.useLegacyCoreDatabases ?? false;
225
231
 
226
232
  // Initialize core services
227
- const logger = createLogger(options.logger);
233
+ // Order matters: events → logs → logger (with PersistentTransport) → cron/jobs (with logger)
228
234
  const cache = createCache(options.cache);
229
235
  const events = createEvents(options.events);
230
- const cron = createCron(options.cron);
231
236
  const sse = createSSE(options.sse);
232
237
  const rateLimiter = createRateLimiter(options.rateLimiter);
233
238
  const errors = createErrors(options.errors);
234
239
 
240
+ // Create logs service with its own database
241
+ const logsAdapter = options.logs?.adapter ?? new KyselyLogsAdapter({
242
+ dbPath: options.logs?.dbPath,
243
+ });
244
+ const logs = createLogs({
245
+ ...options.logs,
246
+ adapter: logsAdapter,
247
+ events,
248
+ });
249
+
250
+ // Create logger with both console and persistent transports
251
+ const persistentTransport = new PersistentTransport(logs, {
252
+ minLevel: options.logs?.minLevel,
253
+ });
254
+ const loggerTransports = [
255
+ new ConsoleTransport(options.logger?.format ?? "pretty"),
256
+ persistentTransport,
257
+ ];
258
+ const logger = createLogger({
259
+ ...options.logger,
260
+ transports: options.logger?.transports ?? loggerTransports,
261
+ });
262
+
263
+ // Cron with logger for scoped logging
264
+ const cron = createCron({
265
+ ...options.cron,
266
+ logger,
267
+ });
268
+
235
269
  // Create adapters - use Kysely by default, or legacy SQLite if requested
236
270
  const jobAdapter = options.jobs?.adapter ?? (useLegacy ? undefined : new KyselyJobAdapter(options.db));
237
271
  const workflowAdapter = options.workflows?.adapter ?? (useLegacy ? undefined : new KyselyWorkflowAdapter(options.db));
238
272
  const auditAdapter = options.audit?.adapter ?? new KyselyAuditAdapter(options.db);
239
273
 
240
- // Jobs can emit events and use Kysely adapter
274
+ // Jobs can emit events and use Kysely adapter, with logger for scoped logging
241
275
  const jobs = createJobs({
242
276
  ...options.jobs,
243
277
  events,
278
+ logger,
244
279
  adapter: jobAdapter,
245
280
  // Disable built-in persistence when using Kysely adapter
246
281
  persist: useLegacy ? options.jobs?.persist : false,
@@ -256,8 +291,6 @@ export class AppServer {
256
291
  });
257
292
 
258
293
  // Processes - still uses its own adapter pattern but can use Kysely
259
- // Note: ProcessesImpl creates its own SqliteProcessAdapter internally
260
- // For full Kysely support, we need to modify processes.ts
261
294
  const processes = createProcesses({
262
295
  ...options.processes,
263
296
  events,
@@ -287,6 +320,7 @@ export class AppServer {
287
320
  audit,
288
321
  websocket,
289
322
  storage,
323
+ logs,
290
324
  };
291
325
 
292
326
  // Resolve circular dependency: workflows needs core for step handlers
@@ -993,6 +1027,7 @@ ${factoryFunction}
993
1027
 
994
1028
  this.coreServices.cron.start();
995
1029
  this.coreServices.jobs.start();
1030
+ await this.coreServices.workflows.resolveDbPath();
996
1031
  await this.coreServices.workflows.resume();
997
1032
  this.coreServices.processes.start();
998
1033
  logger.info("Background services started (cron, jobs, workflows, processes)");
@@ -1407,6 +1442,10 @@ ${factoryFunction}
1407
1442
  // Run user shutdown handlers first (in reverse order - LIFO)
1408
1443
  await this.runShutdownHandlers();
1409
1444
 
1445
+ // Flush and stop logs before other services shut down
1446
+ await this.coreServices.logs.flush();
1447
+ this.coreServices.logs.stop();
1448
+
1410
1449
  // Stop SSE (closes all client connections)
1411
1450
  this.coreServices.sse.shutdown();
1412
1451
 
File without changes