@velajs/vela 1.12.0 → 1.14.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.
Files changed (49) hide show
  1. package/CHANGELOG.md +101 -1
  2. package/dist/application.d.ts +17 -0
  3. package/dist/application.js +94 -3
  4. package/dist/container/container.d.ts +21 -1
  5. package/dist/container/container.js +89 -2
  6. package/dist/container/types.d.ts +27 -0
  7. package/dist/discovery/discovery.service.d.ts +8 -0
  8. package/dist/discovery/discovery.service.js +11 -0
  9. package/dist/entrypoint/entrypoint.registry.d.ts +3 -1
  10. package/dist/entrypoint/entrypoint.registry.js +9 -3
  11. package/dist/event-emitter/event-emitter.module.js +1 -0
  12. package/dist/factory/bootstrap.js +4 -0
  13. package/dist/http/route.manager.js +5 -0
  14. package/dist/i18n/i18n.module.js +5 -0
  15. package/dist/index.d.ts +2 -2
  16. package/dist/index.js +1 -1
  17. package/dist/module/decorators.js +4 -2
  18. package/dist/module/define-module.d.ts +7 -0
  19. package/dist/module/define-module.js +9 -4
  20. package/dist/module/lazy-modules.d.ts +82 -0
  21. package/dist/module/lazy-modules.js +231 -0
  22. package/dist/module/module-loader.d.ts +21 -0
  23. package/dist/module/module-loader.js +99 -24
  24. package/dist/pipeline/index.d.ts +2 -0
  25. package/dist/pipeline/index.js +1 -0
  26. package/dist/pipeline/scoped-components.d.ts +26 -0
  27. package/dist/pipeline/scoped-components.js +27 -0
  28. package/dist/queue/index.d.ts +10 -0
  29. package/dist/queue/index.js +12 -0
  30. package/dist/queue/inline.driver.d.ts +30 -0
  31. package/dist/queue/inline.driver.js +58 -0
  32. package/dist/queue/queue.binding.d.ts +23 -0
  33. package/dist/queue/queue.binding.js +53 -0
  34. package/dist/queue/queue.client.d.ts +20 -0
  35. package/dist/queue/queue.client.js +33 -0
  36. package/dist/queue/queue.decorators.d.ts +23 -0
  37. package/dist/queue/queue.decorators.js +46 -0
  38. package/dist/queue/queue.dispatch.d.ts +36 -0
  39. package/dist/queue/queue.dispatch.js +102 -0
  40. package/dist/queue/queue.module.d.ts +32 -0
  41. package/dist/queue/queue.module.js +80 -0
  42. package/dist/queue/queue.tokens.d.ts +21 -0
  43. package/dist/queue/queue.tokens.js +34 -0
  44. package/dist/queue/queue.types.d.ts +61 -0
  45. package/dist/queue/queue.types.js +4 -0
  46. package/dist/registry/types.d.ts +10 -0
  47. package/dist/schedule/schedule.module.js +3 -0
  48. package/dist/seeder/seeder.module.js +3 -0
  49. package/package.json +5 -1
@@ -0,0 +1,34 @@
1
+ import { InjectionToken } from "../index.js";
2
+ export const PROCESSOR_METADATA = 'vela:queue:processor';
3
+ export const PROCESS_METADATA = 'vela:queue:process';
4
+ /** The driver in effect for a `QueueModule` instance. */ export const QUEUE_DRIVER = new InjectionToken('vela:queue:driver');
5
+ // Token identity must survive Vite HMR re-evals (a consumer module that was
6
+ // NOT re-evaluated still holds the token minted by the previous generation),
7
+ // so the name → token map is anchored on globalThis exactly like the
8
+ // entrypoint kind store and MetadataRegistry state.
9
+ const TOKEN_STORE_KEY = Symbol.for('vela:queue:client-tokens:v1');
10
+ function tokenStore() {
11
+ const g = globalThis;
12
+ return g[TOKEN_STORE_KEY] ??= new Map();
13
+ }
14
+ /**
15
+ * The injection token for a named queue's `QueueClient`:
16
+ *
17
+ * ```ts
18
+ * constructor(@Inject(queueToken('email')) private readonly email: QueueClient) {}
19
+ * ```
20
+ *
21
+ * Memoized per name (HMR-stable). Deliberately NO `InjectionToken` default
22
+ * factory: the container resolves default-factory tokens from the root bucket
23
+ * BEFORE walking module imports, which would break the exported-provider
24
+ * path — the token description (`vela:queue:client:<name>`) keeps the
25
+ * no-provider error readable instead.
26
+ */ export function queueToken(name) {
27
+ const store = tokenStore();
28
+ let token = store.get(name);
29
+ if (!token) {
30
+ token = new InjectionToken(`vela:queue:client:${name}`);
31
+ store.set(name, token);
32
+ }
33
+ return token;
34
+ }
@@ -0,0 +1,61 @@
1
+ /**
2
+ * One job as handed to `@Process` handlers and drivers. Ids are minted by the
3
+ * client via `crypto.randomUUID()` (Web Crypto — edge-safe).
4
+ */
5
+ export interface QueueJob<T = unknown> {
6
+ id: string;
7
+ /** Queue the job was added to (`QueueModule.forRoot({ queues })` name). */
8
+ queue: string;
9
+ /** Job name — matched against `@Process(name)`; unnamed handlers catch the rest. */
10
+ name: string;
11
+ data: T;
12
+ /** Delivery attempt, 1-based. Platform drivers increment on retry. */
13
+ attempt: number;
14
+ }
15
+ export interface AddJobOptions {
16
+ /**
17
+ * Requested delivery delay. Honored only by drivers that support it — the
18
+ * in-core `inline()` driver does not and warns once (log diagnostics).
19
+ */
20
+ delayMs?: number;
21
+ }
22
+ /** The function a driver calls to deliver one job into the app's processors. */
23
+ export type QueueDispatchFn = (job: QueueJob) => Promise<void>;
24
+ export interface QueueDriverBindHooks {
25
+ /**
26
+ * Where fire-and-forget delivery errors go (the inline driver's
27
+ * `immediate` mode has no awaiter to rethrow into). Wired to the
28
+ * container's diagnostics by `QueueDispatchBinding`.
29
+ */
30
+ onError?: (error: unknown, job: QueueJob) => void;
31
+ }
32
+ /**
33
+ * Producer/transport seam. `enqueue` accepts a job for later (or immediate)
34
+ * delivery; drivers that deliver in-process implement `bind` to receive the
35
+ * app's dispatch function. Platform packages (Cloudflare Queues, Redis, …)
36
+ * implement this interface out-of-core.
37
+ */
38
+ export interface QueueDriver {
39
+ readonly kind: string;
40
+ enqueue(job: QueueJob, options?: AddJobOptions): Promise<void>;
41
+ bind?(dispatch: QueueDispatchFn, hooks?: QueueDriverBindHooks): void;
42
+ }
43
+ export interface QueueModuleOptions {
44
+ /**
45
+ * Queue names this instance provides clients for. STRUCTURAL — must be
46
+ * known at `forRoot`/`forRootAsync` call time (clients are options-derived
47
+ * providers); `forRootAsync` callers pass it alongside the factory.
48
+ */
49
+ queues?: string[];
50
+ /** Defaults to the in-core `inline()` driver. */
51
+ driver?: QueueDriver;
52
+ }
53
+ /** Class-level meta written by `@Processor(queueName)` (the 'queue' entrypoint kind). */
54
+ export interface ProcessorMetadata {
55
+ queueName: string;
56
+ }
57
+ /** Per-handler meta written by `@Process(jobName?)`. */
58
+ export interface ProcessMetadata {
59
+ jobName?: string;
60
+ methodName: string | symbol;
61
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * One job as handed to `@Process` handlers and drivers. Ids are minted by the
3
+ * client via `crypto.randomUUID()` (Web Crypto — edge-safe).
4
+ */ /** Per-handler meta written by `@Process(jobName?)`. */ export { };
@@ -81,6 +81,13 @@ export interface DynamicModule {
81
81
  controllers?: Type[];
82
82
  exports?: Array<Type | InjectionToken>;
83
83
  global?: boolean;
84
+ /**
85
+ * Defer this module instance's providers/controllers to first use: nothing
86
+ * constructs at bootstrap; the first resolution of any of its tokens
87
+ * materializes the whole group and replays its lifecycle hooks (memoized).
88
+ * See MODULE_AUTHORING.md "Lazy modules" for the contract.
89
+ */
90
+ lazy?: boolean;
84
91
  }
85
92
  export interface ModuleOptions {
86
93
  providers?: Array<Type | ProviderOptions>;
@@ -88,6 +95,8 @@ export interface ModuleOptions {
88
95
  imports?: ModuleImport[];
89
96
  exports?: Array<Type | InjectionToken>;
90
97
  isGlobal?: boolean;
98
+ /** Defer to first use (see {@link DynamicModule.lazy}). */
99
+ lazy?: boolean;
91
100
  }
92
101
  export interface ModuleMetadata {
93
102
  providers: Array<Type | ProviderOptions>;
@@ -95,4 +104,5 @@ export interface ModuleMetadata {
95
104
  imports: ModuleImport[];
96
105
  exports: Array<Type | InjectionToken>;
97
106
  isGlobal: boolean;
107
+ lazy: boolean;
98
108
  }
@@ -15,6 +15,9 @@ export class ScheduleModule {
15
15
  }
16
16
  ScheduleModule = _ts_decorate([
17
17
  Module({
18
+ // Lazy: the @Cron/@Interval discovery pass runs when ScheduleRegistry is
19
+ // first resolved (executor bootstrap, introspection, first dispatch).
20
+ lazy: true,
18
21
  providers: [
19
22
  ScheduleRegistry
20
23
  ],
@@ -28,6 +28,9 @@ export class SeederModule extends ConfigurableModuleClass {
28
28
  }
29
29
  SeederModule = _ts_decorate([
30
30
  Module({
31
+ // Lazy: the @Seeder metadata scan runs when SeederRegistry is first
32
+ // resolved (runSeeders) — hook replay repopulates it correctly.
33
+ lazy: true,
31
34
  providers: [
32
35
  SeederRegistry
33
36
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@velajs/vela",
3
- "version": "1.12.0",
3
+ "version": "1.14.0",
4
4
  "description": "NestJS-compatible framework for edge runtimes, powered by Hono",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -34,6 +34,10 @@
34
34
  "types": "./dist/i18n/index.d.ts",
35
35
  "import": "./dist/i18n/index.js"
36
36
  },
37
+ "./queue": {
38
+ "types": "./dist/queue/index.d.ts",
39
+ "import": "./dist/queue/index.js"
40
+ },
37
41
  "./storage": {
38
42
  "types": "./dist/storage/index.d.ts",
39
43
  "import": "./dist/storage/index.js"