@getvision/server 0.4.3-d4c761e-develop → 0.4.4-44d79d9-develop

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 (45) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/event-bus.d.ts +87 -0
  3. package/dist/event-bus.d.ts.map +1 -0
  4. package/dist/event-bus.js +265 -0
  5. package/dist/event-bus.js.map +10 -0
  6. package/dist/event-registry.d.ts +79 -0
  7. package/dist/event-registry.d.ts.map +1 -0
  8. package/dist/event-registry.js +93 -0
  9. package/dist/event-registry.js.map +10 -0
  10. package/{src/index.ts → dist/index.d.ts} +14 -28
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +33 -0
  13. package/dist/index.js.map +10 -0
  14. package/dist/router.d.ts +16 -0
  15. package/dist/router.d.ts.map +1 -0
  16. package/dist/router.js +117 -0
  17. package/dist/router.js.map +10 -0
  18. package/dist/service.d.ts +151 -0
  19. package/dist/service.d.ts.map +1 -0
  20. package/dist/service.js +341 -0
  21. package/dist/service.js.map +10 -0
  22. package/dist/types.d.ts +71 -0
  23. package/dist/types.d.ts.map +1 -0
  24. package/dist/types.js +2 -0
  25. package/dist/types.js.map +9 -0
  26. package/dist/vision-app.d.ts +166 -0
  27. package/dist/vision-app.d.ts.map +1 -0
  28. package/dist/vision-app.js +611 -0
  29. package/dist/vision-app.js.map +10 -0
  30. package/dist/vision.d.ts +63 -0
  31. package/dist/vision.d.ts.map +1 -0
  32. package/dist/vision.js +223 -0
  33. package/dist/vision.js.map +10 -0
  34. package/package.json +13 -3
  35. package/.env.example +0 -3
  36. package/.eslintrc.cjs +0 -7
  37. package/.turbo/turbo-build.log +0 -1
  38. package/src/event-bus.ts +0 -409
  39. package/src/event-registry.ts +0 -158
  40. package/src/router.ts +0 -118
  41. package/src/service.ts +0 -618
  42. package/src/types.ts +0 -93
  43. package/src/vision-app.ts +0 -880
  44. package/src/vision.ts +0 -319
  45. package/tsconfig.json +0 -9
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @getvision/server - Meta-framework with built-in observability
3
- *
3
+ *
4
4
  * Features:
5
5
  * - Built on Hono (ultra-fast, edge-ready)
6
6
  * - Built-in Vision Dashboard (tracing, logging)
@@ -8,12 +8,12 @@
8
8
  * - Pub/Sub & Cron via BullMQ (automatic)
9
9
  * - Service builder pattern
10
10
  * - c.span() for custom tracing
11
- *
11
+ *
12
12
  * @example
13
13
  * ```ts
14
14
  * import { Vision } from '@getvision/server'
15
15
  * import { z } from 'zod'
16
- *
16
+ *
17
17
  * const app = new Vision({
18
18
  * service: {
19
19
  * name: 'My API',
@@ -27,7 +27,7 @@
27
27
  * }
28
28
  * }
29
29
  * })
30
- *
30
+ *
31
31
  * const userService = app.service('users')
32
32
  * .endpoint('GET', '/users/:id', schema, async (data, c) => {
33
33
  * // c.span() is built-in!
@@ -39,30 +39,16 @@
39
39
  * .on('user/created', async (event) => {
40
40
  * console.log('User created:', event.data)
41
41
  * })
42
- *
42
+ *
43
43
  * app.start(3000)
44
44
  * ```
45
45
  */
46
-
47
- // Main Vision class
48
- export { Vision, getVisionContext } from './vision-app'
49
- export type { VisionConfig } from './vision-app'
50
-
51
- // Service builder (usually accessed via app.service())
52
- export { ServiceBuilder } from './service'
53
-
54
- // Event bus
55
- export { EventBus } from './event-bus'
56
- export type { EventBusConfig } from './event-bus'
57
-
58
- // Types
59
- export type {
60
- EndpointConfig,
61
- Handler,
62
- VisionContext,
63
- ExtendedContext
64
- } from './types'
65
-
66
- // Re-export from core for convenience
67
- export { VisionCore } from '@getvision/core'
68
- export type * from '@getvision/core'
46
+ export { Vision, getVisionContext } from './vision-app';
47
+ export type { VisionConfig } from './vision-app';
48
+ export { ServiceBuilder } from './service';
49
+ export { EventBus } from './event-bus';
50
+ export type { EventBusConfig } from './event-bus';
51
+ export type { EndpointConfig, Handler, VisionContext, ExtendedContext } from './types';
52
+ export { VisionCore } from '@getvision/core';
53
+ export type * from '@getvision/core';
54
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAGH,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AACvD,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAGhD,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAG1C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AACtC,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAGjD,YAAY,EACV,cAAc,EACd,OAAO,EACP,aAAa,EACb,eAAe,EAChB,MAAM,SAAS,CAAA;AAGhB,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,mBAAmB,iBAAiB,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,33 @@
1
+ import { createRequire } from "node:module";
2
+ var __create = Object.create;
3
+ var __getProtoOf = Object.getPrototypeOf;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __toESM = (mod, isNodeMode, target) => {
8
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
9
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
10
+ for (let key of __getOwnPropNames(mod))
11
+ if (!__hasOwnProp.call(to, key))
12
+ __defProp(to, key, {
13
+ get: () => mod[key],
14
+ enumerable: true
15
+ });
16
+ return to;
17
+ };
18
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
19
+
20
+ // src/index.ts
21
+ import { Vision, getVisionContext } from "./vision-app";
22
+ import { ServiceBuilder } from "./service";
23
+ import { EventBus } from "./event-bus";
24
+ import { VisionCore } from "@getvision/core";
25
+ export {
26
+ getVisionContext,
27
+ VisionCore,
28
+ Vision,
29
+ ServiceBuilder,
30
+ EventBus
31
+ };
32
+
33
+ //# debugId=141F5DC62996839464756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/index.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * @getvision/server - Meta-framework with built-in observability\n * \n * Features:\n * - Built on Hono (ultra-fast, edge-ready)\n * - Built-in Vision Dashboard (tracing, logging)\n * - Type-safe Zod validation\n * - Pub/Sub & Cron via BullMQ (automatic)\n * - Service builder pattern\n * - c.span() for custom tracing\n * \n * @example\n * ```ts\n * import { Vision } from '@getvision/server'\n * import { z } from 'zod'\n * \n * const app = new Vision({\n * service: {\n * name: 'My API',\n * version: '1.0.0'\n * },\n * pubsub: {\n * schemas: {\n * 'user/created': {\n * data: z.object({ userId: z.string() })\n * }\n * }\n * }\n * })\n * \n * const userService = app.service('users')\n * .endpoint('GET', '/users/:id', schema, async (data, c) => {\n * // c.span() is built-in!\n * const user = c.span('db.select', { 'db.table': 'users' }, () => {\n * return db.users.findOne(data.id)\n * })\n * return user\n * })\n * .on('user/created', async (event) => {\n * console.log('User created:', event.data)\n * })\n * \n * app.start(3000)\n * ```\n */\n\n// Main Vision class\nexport { Vision, getVisionContext } from './vision-app'\nexport type { VisionConfig } from './vision-app'\n\n// Service builder (usually accessed via app.service())\nexport { ServiceBuilder } from './service'\n\n// Event bus\nexport { EventBus } from './event-bus'\nexport type { EventBusConfig } from './event-bus'\n\n// Types\nexport type { \n EndpointConfig, \n Handler, \n VisionContext,\n ExtendedContext\n} from './types'\n\n// Re-export from core for convenience\nexport { VisionCore } from '@getvision/core'\nexport type * from '@getvision/core'\n"
6
+ ],
7
+ "mappings": ";;;;;;;;;;;;;;;;;;;;AA+CA;AAIA;AAGA;AAYA;",
8
+ "debugId": "141F5DC62996839464756E2164756E21",
9
+ "names": []
10
+ }
@@ -0,0 +1,16 @@
1
+ import type { Hono } from 'hono';
2
+ import type { EventBus } from './event-bus';
3
+ /**
4
+ * Autoload Vision/Hono sub-apps from a directory structure like app/routes/.../index.ts
5
+ * Each folder becomes a base path. Dynamic segments [id] are converted to :id.
6
+ *
7
+ * Examples:
8
+ * - app/routes/users/index.ts -> /users
9
+ * - app/routes/users/[id]/index.ts -> /users/:id
10
+ * - app/routes/index.ts -> /
11
+ */
12
+ export declare function loadSubApps(app: Hono, routesDir?: string, eventBus?: EventBus): Promise<Array<{
13
+ name: string;
14
+ routes: any[];
15
+ }>>;
16
+ //# sourceMappingURL=router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAIhC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAE3C;;;;;;;;GAQG;AACH,wBAAsB,WAAW,CAAC,GAAG,EAAE,IAAI,EAAE,SAAS,GAAE,MAAuB,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,GAAG,EAAE,CAAA;CAAE,CAAC,CAAC,CAsGrJ"}
package/dist/router.js ADDED
@@ -0,0 +1,117 @@
1
+ import { createRequire } from "node:module";
2
+ var __create = Object.create;
3
+ var __getProtoOf = Object.getPrototypeOf;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __toESM = (mod, isNodeMode, target) => {
8
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
9
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
10
+ for (let key of __getOwnPropNames(mod))
11
+ if (!__hasOwnProp.call(to, key))
12
+ __defProp(to, key, {
13
+ get: () => mod[key],
14
+ enumerable: true
15
+ });
16
+ return to;
17
+ };
18
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
19
+
20
+ // src/router.ts
21
+ import { readdirSync, statSync } from "fs";
22
+ import { join, resolve, relative, sep } from "path";
23
+ import { pathToFileURL } from "url";
24
+ async function loadSubApps(app, routesDir = "./app/routes", eventBus) {
25
+ const mounted = [];
26
+ const allSubAppSummaries = [];
27
+ function toBasePath(dirPath) {
28
+ const rel = relative(resolve(routesDir), resolve(dirPath));
29
+ if (!rel || rel === "" || rel === ".")
30
+ return "/";
31
+ const segments = rel.split(sep).filter(Boolean).map((s) => {
32
+ if (s.startsWith("[") && s.endsWith("]"))
33
+ return `:${s.slice(1, -1)}`;
34
+ return s;
35
+ });
36
+ return "/" + segments.join("/");
37
+ }
38
+ function isDynamicSegment(name) {
39
+ return name.startsWith("[") && name.endsWith("]");
40
+ }
41
+ async function scan(dir) {
42
+ const entries = readdirSync(dir);
43
+ const hasTs = entries.includes("index.ts");
44
+ const hasJs = entries.includes("index.js");
45
+ if (hasTs || hasJs) {
46
+ const indexFile = resolve(dir, hasTs ? "index.ts" : "index.js");
47
+ const modUrl = pathToFileURL(indexFile).href;
48
+ const mod = await import(modUrl);
49
+ const subApp = mod?.default;
50
+ if (subApp) {
51
+ if (eventBus && typeof subApp?.setEventBus === "function") {
52
+ subApp.setEventBus(eventBus);
53
+ }
54
+ const base = toBasePath(dir);
55
+ try {
56
+ if (typeof subApp?.service === "function") {
57
+ await subApp.buildAllServices?.();
58
+ const summaries = subApp.getServiceSummaries?.();
59
+ if (Array.isArray(summaries) && summaries.length > 0) {
60
+ const prefixedSummaries = summaries.map((s) => ({
61
+ ...s,
62
+ routes: s.routes.map((r) => ({
63
+ ...r,
64
+ path: base === "/" ? r.path : base + (r.path === "/" ? "" : r.path)
65
+ }))
66
+ }));
67
+ allSubAppSummaries.push(...prefixedSummaries);
68
+ }
69
+ }
70
+ } catch (e) {
71
+ console.error(`❌ Error preparing sub-app ${dir}:`, e?.message || e);
72
+ }
73
+ const routes = subApp?.routes;
74
+ if (Array.isArray(routes)) {
75
+ app.route(base, subApp);
76
+ mounted.push({ base });
77
+ }
78
+ }
79
+ }
80
+ const sortedEntries = [...entries].sort((a, b) => {
81
+ const aIsDynamic = isDynamicSegment(a);
82
+ const bIsDynamic = isDynamicSegment(b);
83
+ if (aIsDynamic && !bIsDynamic)
84
+ return 1;
85
+ if (!aIsDynamic && bIsDynamic)
86
+ return -1;
87
+ return a.localeCompare(b);
88
+ });
89
+ for (const name of sortedEntries) {
90
+ const full = join(dir, name);
91
+ const st = statSync(full);
92
+ if (st.isDirectory())
93
+ await scan(full);
94
+ }
95
+ }
96
+ try {
97
+ statSync(routesDir);
98
+ } catch {
99
+ return [];
100
+ }
101
+ await scan(routesDir);
102
+ const mergedServices = new Map;
103
+ for (const summary of allSubAppSummaries) {
104
+ if (mergedServices.has(summary.name)) {
105
+ const existing = mergedServices.get(summary.name);
106
+ existing.routes.push(...summary.routes);
107
+ } else {
108
+ mergedServices.set(summary.name, { name: summary.name, routes: [...summary.routes] });
109
+ }
110
+ }
111
+ return Array.from(mergedServices.values());
112
+ }
113
+ export {
114
+ loadSubApps
115
+ };
116
+
117
+ //# debugId=69C3F80F4267D85A64756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/router.ts"],
4
+ "sourcesContent": [
5
+ "import type { Hono } from 'hono'\nimport { readdirSync, statSync } from 'fs'\nimport { join, resolve, relative, sep } from 'path'\nimport { pathToFileURL } from 'url'\nimport type { EventBus } from './event-bus'\n\n/**\n * Autoload Vision/Hono sub-apps from a directory structure like app/routes/.../index.ts\n * Each folder becomes a base path. Dynamic segments [id] are converted to :id.\n *\n * Examples:\n * - app/routes/users/index.ts -> /users\n * - app/routes/users/[id]/index.ts -> /users/:id\n * - app/routes/index.ts -> /\n */\nexport async function loadSubApps(app: Hono, routesDir: string = './app/routes', eventBus?: EventBus): Promise<Array<{ name: string; routes: any[] }>> {\n const mounted: Array<{ base: string }> = []\n const allSubAppSummaries: Array<{ name: string; routes: any[] }> = []\n\n function toBasePath(dirPath: string): string {\n const rel = relative(resolve(routesDir), resolve(dirPath))\n if (!rel || rel === '' || rel === '.' ) return '/'\n const segments = rel.split(sep).filter(Boolean).map((s) => {\n if (s.startsWith('[') && s.endsWith(']')) return `:${s.slice(1, -1)}`\n return s\n })\n return '/' + segments.join('/')\n }\n\n function isDynamicSegment(name: string): boolean {\n return name.startsWith('[') && name.endsWith(']')\n }\n\n async function scan(dir: string) {\n const entries = readdirSync(dir)\n // If folder contains index.ts or index.js, treat it as a sub-app root\n const hasTs = entries.includes('index.ts')\n const hasJs = entries.includes('index.js')\n if (hasTs || hasJs) {\n const indexFile = resolve(dir, hasTs ? 'index.ts' : 'index.js')\n const modUrl = pathToFileURL(indexFile).href\n const mod: any = await import(modUrl)\n const subApp = mod?.default\n if (subApp) {\n // Inject EventBus into sub-app if it's a Vision instance\n if (eventBus && typeof subApp?.setEventBus === 'function') {\n subApp.setEventBus(eventBus)\n }\n const base = toBasePath(dir)\n // If it's a Vision sub-app, build its services before mounting\n try {\n if (typeof (subApp as any)?.service === 'function') {\n await (subApp as any).buildAllServices?.()\n // Collect sub-app services/routes for bulk registration later\n const summaries = (subApp as any).getServiceSummaries?.()\n if (Array.isArray(summaries) && summaries.length > 0) {\n // Prefix all route paths with the base path\n const prefixedSummaries = summaries.map(s => ({\n ...s,\n routes: s.routes.map((r: any) => ({\n ...r,\n path: base === '/' ? r.path : base + (r.path === '/' ? '' : r.path)\n }))\n }))\n allSubAppSummaries.push(...prefixedSummaries)\n }\n }\n } catch (e) {\n console.error(`❌ Error preparing sub-app ${dir}:`, (e as any)?.message || e)\n }\n // Mount the sub-app only if it looks like a Hono/Vision instance with routes\n const routes = (subApp as any)?.routes\n if (Array.isArray(routes)) {\n ;(app as any).route(base, subApp)\n mounted.push({ base })\n }\n }\n }\n // Recurse into child directories\n // Sort entries: static folders first, then dynamic [param] folders\n // This ensures static routes have priority over dynamic routes\n const sortedEntries = [...entries].sort((a, b) => {\n const aIsDynamic = isDynamicSegment(a)\n const bIsDynamic = isDynamicSegment(b)\n if (aIsDynamic && !bIsDynamic) return 1 // dynamic after static\n if (!aIsDynamic && bIsDynamic) return -1 // static before dynamic\n return a.localeCompare(b) // alphabetical within same type\n })\n for (const name of sortedEntries) {\n const full = join(dir, name)\n const st = statSync(full)\n if (st.isDirectory()) await scan(full)\n }\n }\n\n // Only scan if directory exists\n try {\n statSync(routesDir)\n } catch {\n return []\n }\n\n await scan(routesDir)\n \n // Merge services by name (combine routes from same service name)\n const mergedServices = new Map<string, { name: string; routes: any[] }>()\n for (const summary of allSubAppSummaries) {\n if (mergedServices.has(summary.name)) {\n const existing = mergedServices.get(summary.name)!\n existing.routes.push(...summary.routes)\n } else {\n mergedServices.set(summary.name, { name: summary.name, routes: [...summary.routes] })\n }\n }\n \n // Return merged services (don't register here - let caller handle it)\n return Array.from(mergedServices.values())\n}\n"
6
+ ],
7
+ "mappings": "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",
8
+ "debugId": "69C3F80F4267D85A64756E2164756E21",
9
+ "names": []
10
+ }
@@ -0,0 +1,151 @@
1
+ import type { Hono, Context, MiddlewareHandler, Env, Input } from 'hono';
2
+ import type { z } from 'zod';
3
+ import { VisionCore } from '@getvision/core';
4
+ import type { EndpointConfig, Handler } from './types';
5
+ import type { EventBus } from './event-bus';
6
+ /**
7
+ * Event schema map - accumulates event types as they're registered
8
+ */
9
+ type EventSchemaMap = Record<string, z.ZodSchema<any>>;
10
+ /**
11
+ * ServiceBuilder - Builder pattern API for defining services
12
+ *
13
+ * Automatically infers event types from Zod schemas passed to .on()
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * const userService = app.service('users')
18
+ * .use(logger())
19
+ * .endpoint('GET', '/users/:id', { input, output }, handler)
20
+ * .on('user/created', {
21
+ * schema: z.object({ userId: z.string(), email: z.string() }),
22
+ * handler: async (event) => {
23
+ * // event is fully typed: { userId: string, email: string }
24
+ * }
25
+ * })
26
+ * ```
27
+ */
28
+ export declare class ServiceBuilder<TEvents extends EventSchemaMap = {}, E extends Env = Env, I extends Input = {}> {
29
+ private name;
30
+ private eventBus;
31
+ private visionCore?;
32
+ private endpoints;
33
+ private eventHandlers;
34
+ private cronJobs;
35
+ private globalMiddleware;
36
+ private eventSchemas;
37
+ constructor(name: string, eventBus: EventBus, visionCore?: VisionCore | undefined);
38
+ /**
39
+ * Add global middleware for all endpoints in this service
40
+ */
41
+ use(...middleware: MiddlewareHandler<E, string, any, any>[]): this;
42
+ /**
43
+ * Get service name (capitalized) and route metadata without registering
44
+ */
45
+ getRoutesMetadata(): Array<{
46
+ method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
47
+ path: string;
48
+ queryParams?: any;
49
+ requestBody?: any;
50
+ responseBody?: any;
51
+ }>;
52
+ getDisplayName(): string;
53
+ /**
54
+ * Define an HTTP endpoint with Zod validation
55
+ *
56
+ * @example
57
+ * ```ts
58
+ * service.endpoint(
59
+ * 'GET',
60
+ * '/users/:id',
61
+ * {
62
+ * input: z.object({ id: z.string() }),
63
+ * output: z.object({ id: z.string(), name: z.string() })
64
+ * },
65
+ * async ({ id }, c) => {
66
+ * return { id, name: 'John' }
67
+ * },
68
+ * { middleware: [authMiddleware] }
69
+ * )
70
+ * ```
71
+ */
72
+ endpoint<TInputSchema extends z.ZodType, TOutputSchema extends z.ZodType | undefined, PPath extends string>(method: EndpointConfig['method'], path: PPath, schema: {
73
+ input: TInputSchema;
74
+ output?: TOutputSchema;
75
+ }, handler: Handler<z.infer<TInputSchema>, TOutputSchema extends z.ZodType ? z.infer<TOutputSchema> : any, TEvents, E, PPath, I>, config?: Partial<EndpointConfig>): this;
76
+ /**
77
+ * Subscribe to events with Zod schema validation
78
+ *
79
+ * Automatically infers the event type from the Zod schema.
80
+ * TypeScript will ensure that c.emit() calls match the registered schema.
81
+ *
82
+ * @example
83
+ * ```ts
84
+ * service.on('user/created', {
85
+ * schema: z.object({
86
+ * userId: z.string().uuid(),
87
+ * email: z.string().email()
88
+ * }),
89
+ * description: 'User account created',
90
+ * icon: '👤',
91
+ * tags: ['user', 'auth'],
92
+ * handler: async (event) => {
93
+ * // event is fully typed: { userId: string, email: string }
94
+ * console.log('User created:', event.email)
95
+ * }
96
+ * })
97
+ * ```
98
+ */
99
+ on<K extends string, T extends Record<string, any>>(eventName: K, config: {
100
+ schema: z.ZodSchema<T>;
101
+ description?: string;
102
+ icon?: string;
103
+ tags?: string[];
104
+ /**
105
+ * Max number of concurrent jobs this handler will process.
106
+ * Falls back to EventBus config.workerConcurrency (or 1).
107
+ */
108
+ concurrency?: number;
109
+ handler: (event: T, c: Context<E, any, I>) => Promise<void>;
110
+ }): ServiceBuilder<TEvents & {
111
+ [key in K]: T;
112
+ }, E, I>;
113
+ /**
114
+ * Schedule a cron job using BullMQ Repeatable
115
+ *
116
+ * @example
117
+ * ```ts
118
+ * service.cron('0 0 * * *', {
119
+ * description: 'Daily cleanup',
120
+ * icon: '🧹',
121
+ * tags: ['maintenance'],
122
+ * handler: async (c) => {
123
+ * console.log('Daily cleanup')
124
+ * }
125
+ * })
126
+ * ```
127
+ */
128
+ cron(schedule: string, config: {
129
+ description?: string;
130
+ icon?: string;
131
+ tags?: string[];
132
+ handler: (context: any) => Promise<void>;
133
+ }): this;
134
+ /**
135
+ * Setup BullMQ repeatable job for cron
136
+ */
137
+ private setupCronJob;
138
+ /**
139
+ * Build and register all endpoints with Hono
140
+ */
141
+ build(app: Hono, servicesAccumulator?: Array<{
142
+ name: string;
143
+ routes: any[];
144
+ }>): {
145
+ endpoints: any[];
146
+ eventHandlers: any[];
147
+ cronJobs: any[];
148
+ };
149
+ }
150
+ export {};
151
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}