@donkeylabs/server 0.5.1 → 0.6.3

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/core.ts CHANGED
@@ -11,6 +11,7 @@ import type { SSE } from "./core/sse";
11
11
  import type { RateLimiter } from "./core/rate-limiter";
12
12
  import type { Errors, CustomErrorRegistry } from "./core/errors";
13
13
  import type { Workflows } from "./core/workflows";
14
+ import type { Processes } from "./core/processes";
14
15
 
15
16
  export interface PluginRegistry {}
16
17
 
@@ -54,6 +55,7 @@ export interface CoreServices {
54
55
  rateLimiter: RateLimiter;
55
56
  errors: Errors;
56
57
  workflows: Workflows;
58
+ processes: Processes;
57
59
  }
58
60
 
59
61
  /**
package/src/harness.ts CHANGED
@@ -12,6 +12,7 @@ import {
12
12
  createRateLimiter,
13
13
  createErrors,
14
14
  createWorkflows,
15
+ createProcesses,
15
16
  } from "./core/index";
16
17
 
17
18
  /**
@@ -36,6 +37,7 @@ export async function createTestHarness(targetPlugin: Plugin, dependencies: Plug
36
37
  const rateLimiter = createRateLimiter();
37
38
  const errors = createErrors();
38
39
  const workflows = createWorkflows({ events, jobs, sse });
40
+ const processes = createProcesses({ events, autoRecoverOrphans: false });
39
41
 
40
42
  const core: CoreServices = {
41
43
  db,
@@ -49,6 +51,7 @@ export async function createTestHarness(targetPlugin: Plugin, dependencies: Plug
49
51
  rateLimiter,
50
52
  errors,
51
53
  workflows,
54
+ processes,
52
55
  };
53
56
 
54
57
  const manager = new PluginManager(core);
package/src/server.ts CHANGED
@@ -15,6 +15,7 @@ import {
15
15
  createRateLimiter,
16
16
  createErrors,
17
17
  createWorkflows,
18
+ createProcesses,
18
19
  extractClientIP,
19
20
  HttpError,
20
21
  type LoggerConfig,
@@ -26,6 +27,7 @@ import {
26
27
  type RateLimiterConfig,
27
28
  type ErrorsConfig,
28
29
  type WorkflowsConfig,
30
+ type ProcessesConfig,
29
31
  } from "./core/index";
30
32
  import { zodSchemaToTs } from "./generator/zod-to-ts";
31
33
 
@@ -60,6 +62,7 @@ export interface ServerConfig {
60
62
  rateLimiter?: RateLimiterConfig;
61
63
  errors?: ErrorsConfig;
62
64
  workflows?: WorkflowsConfig;
65
+ processes?: ProcessesConfig;
63
66
  }
64
67
 
65
68
  export class AppServer {
@@ -88,6 +91,10 @@ export class AppServer {
88
91
  jobs,
89
92
  sse,
90
93
  });
94
+ const processes = createProcesses({
95
+ ...options.processes,
96
+ events,
97
+ });
91
98
 
92
99
  this.coreServices = {
93
100
  db: options.db,
@@ -101,6 +108,7 @@ export class AppServer {
101
108
  rateLimiter,
102
109
  errors,
103
110
  workflows,
111
+ processes,
104
112
  };
105
113
 
106
114
  this.manager = new PluginManager(this.coreServices);
@@ -226,12 +234,19 @@ export class AppServer {
226
234
  outputSource?: string;
227
235
  }> = [];
228
236
 
237
+ const routesWithoutOutput: string[] = [];
238
+
229
239
  for (const router of this.routers) {
230
240
  for (const route of router.getRoutes()) {
231
241
  const parts = route.name.split(".");
232
242
  const routeName = parts[parts.length - 1] || route.name;
233
243
  const prefix = parts.slice(0, -1).join(".");
234
244
 
245
+ // Track typed routes without explicit output schema
246
+ if (route.handler === "typed" && !route.output) {
247
+ routesWithoutOutput.push(route.name);
248
+ }
249
+
235
250
  routes.push({
236
251
  name: route.name,
237
252
  prefix,
@@ -243,6 +258,17 @@ export class AppServer {
243
258
  }
244
259
  }
245
260
 
261
+ // Warn about routes missing output schemas
262
+ if (routesWithoutOutput.length > 0) {
263
+ logger.warn(
264
+ `${routesWithoutOutput.length} route(s) missing output schema - output type will be 'void'`,
265
+ { routes: routesWithoutOutput }
266
+ );
267
+ logger.debug(
268
+ "Tip: Add an 'output' Zod schema to define the return type, or ensure handlers return nothing"
269
+ );
270
+ }
271
+
246
272
  // Generate the client code
247
273
  const code = this.generateClientCode(routes);
248
274
 
@@ -334,7 +360,7 @@ export function createApi(options?: ClientOptions) {
334
360
  if (r.handler !== "typed") return "";
335
361
  const routeNs = toPascalCase(r.routeName);
336
362
  const inputType = r.inputSource ?? "Record<string, never>";
337
- const outputType = r.outputSource ?? "unknown";
363
+ const outputType = r.outputSource ?? "void";
338
364
  return `${indent}export namespace ${routeNs} {
339
365
  ${indent} export type Input = Expand<${inputType}>;
340
366
  ${indent} export type Output = Expand<${outputType}>;
@@ -458,7 +484,8 @@ ${factoryFunction}
458
484
  this.coreServices.cron.start();
459
485
  this.coreServices.jobs.start();
460
486
  await this.coreServices.workflows.resume();
461
- logger.info("Background services started (cron, jobs, workflows)");
487
+ this.coreServices.processes.start();
488
+ logger.info("Background services started (cron, jobs, workflows, processes)");
462
489
 
463
490
  for (const router of this.routers) {
464
491
  for (const route of router.getRoutes()) {
@@ -677,7 +704,8 @@ ${factoryFunction}
677
704
  this.coreServices.cron.start();
678
705
  this.coreServices.jobs.start();
679
706
  await this.coreServices.workflows.resume();
680
- logger.info("Background services started (cron, jobs, workflows)");
707
+ this.coreServices.processes.start();
708
+ logger.info("Background services started (cron, jobs, workflows, processes)");
681
709
 
682
710
  // 4. Build route map
683
711
  for (const router of this.routers) {
@@ -817,6 +845,7 @@ ${factoryFunction}
817
845
  this.coreServices.sse.shutdown();
818
846
 
819
847
  // Stop background services
848
+ await this.coreServices.processes.shutdown();
820
849
  await this.coreServices.workflows.stop();
821
850
  await this.coreServices.jobs.stop();
822
851
  await this.coreServices.cron.stop();