@donkeylabs/server 1.1.19 → 1.1.20
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/package.json +1 -1
- package/src/core/events.ts +36 -0
- package/src/core.ts +46 -0
- package/src/index.ts +4 -1
package/package.json
CHANGED
package/src/core/events.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
// Core Events Service
|
|
2
2
|
// Pub/sub async event queue
|
|
3
3
|
|
|
4
|
+
import type { EventRegistry } from "../core";
|
|
5
|
+
|
|
4
6
|
export interface EventHandler<T = any> {
|
|
5
7
|
(data: T): void | Promise<void>;
|
|
6
8
|
}
|
|
@@ -25,10 +27,44 @@ export interface EventsConfig {
|
|
|
25
27
|
maxHistorySize?: number;
|
|
26
28
|
}
|
|
27
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Check if EventRegistry has any keys (is augmented)
|
|
32
|
+
*/
|
|
33
|
+
type HasEvents = keyof EventRegistry extends never ? false : true;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Events service interface.
|
|
37
|
+
* When EventRegistry is augmented (via generated types), emit/on become fully typed.
|
|
38
|
+
* Otherwise, falls back to generic string event names.
|
|
39
|
+
*/
|
|
28
40
|
export interface Events {
|
|
41
|
+
/**
|
|
42
|
+
* Emit a typed event (when EventRegistry is augmented)
|
|
43
|
+
*/
|
|
44
|
+
emit<K extends keyof EventRegistry>(event: K, data: EventRegistry[K]): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Emit an untyped event (fallback for dynamic event names)
|
|
47
|
+
*/
|
|
29
48
|
emit<T = any>(event: string, data: T): Promise<void>;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Subscribe to a typed event (when EventRegistry is augmented)
|
|
52
|
+
*/
|
|
53
|
+
on<K extends keyof EventRegistry>(event: K, handler: EventHandler<EventRegistry[K]>): Subscription;
|
|
54
|
+
/**
|
|
55
|
+
* Subscribe to an untyped event (fallback for patterns like "user.*")
|
|
56
|
+
*/
|
|
30
57
|
on<T = any>(event: string, handler: EventHandler<T>): Subscription;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Subscribe to a typed event once (when EventRegistry is augmented)
|
|
61
|
+
*/
|
|
62
|
+
once<K extends keyof EventRegistry>(event: K, handler: EventHandler<EventRegistry[K]>): Subscription;
|
|
63
|
+
/**
|
|
64
|
+
* Subscribe to an untyped event once
|
|
65
|
+
*/
|
|
31
66
|
once<T = any>(event: string, handler: EventHandler<T>): Subscription;
|
|
67
|
+
|
|
32
68
|
off(event: string, handler?: EventHandler): void;
|
|
33
69
|
getHistory(event: string, limit?: number): Promise<EventRecord[]>;
|
|
34
70
|
}
|
package/src/core.ts
CHANGED
|
@@ -24,6 +24,52 @@ export interface ClientConfig {
|
|
|
24
24
|
|
|
25
25
|
export type EventSchemas = Record<string, z.ZodType<any>>;
|
|
26
26
|
|
|
27
|
+
/**
|
|
28
|
+
* Registry for server-level events.
|
|
29
|
+
* Augment this interface to add typed events:
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* // In generated types or app's types file
|
|
34
|
+
* declare module "@donkeylabs/server" {
|
|
35
|
+
* interface EventRegistry {
|
|
36
|
+
* "order.created": { orderId: string; total: number };
|
|
37
|
+
* "user.signup": { userId: string; email: string };
|
|
38
|
+
* }
|
|
39
|
+
* }
|
|
40
|
+
*
|
|
41
|
+
* // Now ctx.core.events.emit("order.created", {...}) is typed
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
|
45
|
+
export interface EventRegistry {}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Define server-level events with Zod schemas.
|
|
49
|
+
* Events defined here will be typed and available across the app.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```ts
|
|
53
|
+
* // src/events.ts
|
|
54
|
+
* import { z } from "zod";
|
|
55
|
+
* import { defineEvents } from "@donkeylabs/server";
|
|
56
|
+
*
|
|
57
|
+
* export const events = defineEvents({
|
|
58
|
+
* "order.created": z.object({
|
|
59
|
+
* orderId: z.string(),
|
|
60
|
+
* total: z.number(),
|
|
61
|
+
* }),
|
|
62
|
+
* "user.signup": z.object({
|
|
63
|
+
* userId: z.string(),
|
|
64
|
+
* email: z.string(),
|
|
65
|
+
* }),
|
|
66
|
+
* });
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
export function defineEvents<T extends EventSchemas>(events: T): T {
|
|
70
|
+
return events;
|
|
71
|
+
}
|
|
72
|
+
|
|
27
73
|
export type Register<
|
|
28
74
|
Service = void,
|
|
29
75
|
Schema = {},
|
package/src/index.ts
CHANGED
|
@@ -46,6 +46,10 @@ export {
|
|
|
46
46
|
createPlugin,
|
|
47
47
|
PluginManager,
|
|
48
48
|
PluginContext,
|
|
49
|
+
// Events
|
|
50
|
+
defineEvents,
|
|
51
|
+
type EventRegistry,
|
|
52
|
+
type EventSchemas,
|
|
49
53
|
type PluginRegistry,
|
|
50
54
|
type PluginHandlerRegistry,
|
|
51
55
|
type PluginMiddlewareRegistry,
|
|
@@ -57,7 +61,6 @@ export {
|
|
|
57
61
|
type InferHandlers,
|
|
58
62
|
type InferMiddleware,
|
|
59
63
|
type InferDependencies,
|
|
60
|
-
type EventSchemas,
|
|
61
64
|
// Custom services registry
|
|
62
65
|
type ServiceRegistry,
|
|
63
66
|
} from "./core";
|