@fluojs/cron 1.0.0-beta.1

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 (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.ko.md +183 -0
  3. package/README.md +183 -0
  4. package/dist/decorators.d.ts +41 -0
  5. package/dist/decorators.d.ts.map +1 -0
  6. package/dist/decorators.js +116 -0
  7. package/dist/distributed-lock-manager.d.ts +38 -0
  8. package/dist/distributed-lock-manager.d.ts.map +1 -0
  9. package/dist/distributed-lock-manager.js +181 -0
  10. package/dist/expressions.d.ts +13 -0
  11. package/dist/expressions.d.ts.map +1 -0
  12. package/dist/expressions.js +12 -0
  13. package/dist/index.d.ts +8 -0
  14. package/dist/index.d.ts.map +1 -0
  15. package/dist/index.js +7 -0
  16. package/dist/metadata.d.ts +17 -0
  17. package/dist/metadata.d.ts.map +1 -0
  18. package/dist/metadata.js +78 -0
  19. package/dist/module.d.ts +31 -0
  20. package/dist/module.d.ts.map +1 -0
  21. package/dist/module.js +95 -0
  22. package/dist/scheduler.d.ts +3 -0
  23. package/dist/scheduler.d.ts.map +1 -0
  24. package/dist/scheduler.js +8 -0
  25. package/dist/service.d.ts +118 -0
  26. package/dist/service.d.ts.map +1 -0
  27. package/dist/service.js +528 -0
  28. package/dist/status.d.ts +32 -0
  29. package/dist/status.d.ts.map +1 -0
  30. package/dist/status.js +107 -0
  31. package/dist/task-discovery.d.ts +8 -0
  32. package/dist/task-discovery.d.ts.map +1 -0
  33. package/dist/task-discovery.js +104 -0
  34. package/dist/task-runner.d.ts +15 -0
  35. package/dist/task-runner.d.ts.map +1 -0
  36. package/dist/task-runner.js +87 -0
  37. package/dist/tokens.d.ts +7 -0
  38. package/dist/tokens.d.ts.map +1 -0
  39. package/dist/tokens.js +4 -0
  40. package/dist/types.d.ts +206 -0
  41. package/dist/types.d.ts.map +1 -0
  42. package/dist/types.js +1 -0
  43. package/package.json +55 -0
@@ -0,0 +1,104 @@
1
+ import { getClassDiMetadata } from '@fluojs/core/internal';
2
+ import { getSchedulingTaskMetadataEntries } from './metadata.js';
3
+ export function buildDefaultTaskName(targetName, methodName) {
4
+ return `${targetName}.${methodName}`;
5
+ }
6
+ export function createLockKey(prefix, taskName) {
7
+ return `${prefix}:${taskName}`;
8
+ }
9
+ export function methodKeyToName(methodKey) {
10
+ return typeof methodKey === 'symbol' ? methodKey.toString() : methodKey;
11
+ }
12
+ export function discoverCronTaskDescriptors(compiledModules, options, logger) {
13
+ const seen = new Map();
14
+ const descriptors = [];
15
+ for (const candidate of collectDiscoveryCandidates(compiledModules)) {
16
+ const entries = getSchedulingTaskMetadataEntries(candidate.targetType.prototype);
17
+ if (candidate.scope !== 'singleton') {
18
+ if (entries.length > 0) {
19
+ logger.warn(`${candidate.targetType.name} in module ${candidate.moduleName} declares scheduling methods (@Cron/@Interval/@Timeout) but is registered with ${candidate.scope} scope. Scheduling tasks are run only for singleton providers.`, 'CronLifecycleService');
20
+ }
21
+ continue;
22
+ }
23
+ for (const entry of entries) {
24
+ const methodName = methodKeyToName(entry.propertyKey);
25
+ const taskName = entry.metadata.options.name ?? buildDefaultTaskName(candidate.targetType.name, methodName);
26
+ const seenMethods = seen.get(candidate.targetType) ?? new Set();
27
+ const lockTtlMs = entry.metadata.options.lockTtlMs ?? options.distributed.lockTtlMs;
28
+ if (seenMethods.has(methodName)) {
29
+ continue;
30
+ }
31
+ seenMethods.add(methodName);
32
+ seen.set(candidate.targetType, seenMethods);
33
+ const descriptor = {
34
+ afterRun: entry.metadata.options.afterRun,
35
+ beforeRun: entry.metadata.options.beforeRun,
36
+ distributed: entry.metadata.options.distributed ?? true,
37
+ kind: entry.metadata.kind,
38
+ lockKey: createLockKey(options.distributed.keyPrefix, entry.metadata.options.key ?? taskName),
39
+ lockTtlMs,
40
+ methodKey: entry.propertyKey,
41
+ methodName,
42
+ moduleName: candidate.moduleName,
43
+ onError: entry.metadata.options.onError,
44
+ onSuccess: entry.metadata.options.onSuccess,
45
+ targetName: candidate.targetType.name,
46
+ taskName,
47
+ token: candidate.token
48
+ };
49
+ if (entry.metadata.kind === 'cron') {
50
+ descriptor.expression = entry.metadata.expression;
51
+ descriptor.timezone = entry.metadata.options.timezone;
52
+ } else {
53
+ descriptor.ms = entry.metadata.ms;
54
+ }
55
+ descriptors.push(descriptor);
56
+ }
57
+ }
58
+ return descriptors;
59
+ }
60
+ function scopeFromProvider(provider) {
61
+ if (typeof provider === 'function') {
62
+ return getClassDiMetadata(provider)?.scope ?? 'singleton';
63
+ }
64
+ if ('useClass' in provider) {
65
+ return provider.scope ?? getClassDiMetadata(provider.useClass)?.scope ?? 'singleton';
66
+ }
67
+ return 'scope' in provider ? provider.scope ?? 'singleton' : 'singleton';
68
+ }
69
+ function isClassProvider(provider) {
70
+ return typeof provider === 'object' && provider !== null && 'useClass' in provider;
71
+ }
72
+ function collectDiscoveryCandidates(compiledModules) {
73
+ const candidates = [];
74
+ for (const compiledModule of compiledModules) {
75
+ for (const provider of compiledModule.definition.providers ?? []) {
76
+ if (typeof provider === 'function') {
77
+ candidates.push({
78
+ moduleName: compiledModule.type.name,
79
+ scope: scopeFromProvider(provider),
80
+ targetType: provider,
81
+ token: provider
82
+ });
83
+ continue;
84
+ }
85
+ if (isClassProvider(provider)) {
86
+ candidates.push({
87
+ moduleName: compiledModule.type.name,
88
+ scope: scopeFromProvider(provider),
89
+ targetType: provider.useClass,
90
+ token: provider.provide
91
+ });
92
+ }
93
+ }
94
+ for (const controller of compiledModule.definition.controllers ?? []) {
95
+ candidates.push({
96
+ moduleName: compiledModule.type.name,
97
+ scope: scopeFromProvider(controller),
98
+ targetType: controller,
99
+ token: controller
100
+ });
101
+ }
102
+ }
103
+ return candidates;
104
+ }
@@ -0,0 +1,15 @@
1
+ import type { Container } from '@fluojs/di';
2
+ import type { ApplicationLogger } from '@fluojs/runtime';
3
+ import type { CronTaskDescriptor } from './types.js';
4
+ export declare class CronTaskRunner {
5
+ private readonly runtimeContainer;
6
+ private readonly logger;
7
+ constructor(runtimeContainer: Container, logger: ApplicationLogger);
8
+ executeTask(descriptor: CronTaskDescriptor, postRunErrorProvider?: () => Error | Promise<Error | undefined> | undefined): Promise<unknown>;
9
+ private resolveTaskInvocation;
10
+ private runTaskBeforeHook;
11
+ private runTaskSuccessHook;
12
+ private runTaskErrorHook;
13
+ private runTaskAfterHook;
14
+ }
15
+ //# sourceMappingURL=task-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-runner.d.ts","sourceRoot":"","sources":["../src/task-runner.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAOrD,qBAAa,cAAc;IAEvB,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM;gBADN,gBAAgB,EAAE,SAAS,EAC3B,MAAM,EAAE,iBAAiB;IAGtC,WAAW,CACf,UAAU,EAAE,kBAAkB,EAC9B,oBAAoB,CAAC,EAAE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC,GAAG,SAAS,GAC1E,OAAO,CAAC,OAAO,CAAC;YA8BL,qBAAqB;YA8CrB,iBAAiB;YAQjB,kBAAkB;YAQlB,gBAAgB;YAUhB,gBAAgB;CAW/B"}
@@ -0,0 +1,87 @@
1
+ export class CronTaskRunner {
2
+ constructor(runtimeContainer, logger) {
3
+ this.runtimeContainer = runtimeContainer;
4
+ this.logger = logger;
5
+ }
6
+ async executeTask(descriptor, postRunErrorProvider) {
7
+ const taskInvocation = await this.resolveTaskInvocation(descriptor);
8
+ if (!taskInvocation) {
9
+ return undefined;
10
+ }
11
+ let taskError;
12
+ try {
13
+ await this.runTaskBeforeHook(descriptor);
14
+ await Promise.resolve(taskInvocation.callable.call(taskInvocation.instance));
15
+ const postRunError = await postRunErrorProvider?.();
16
+ if (postRunError) {
17
+ throw postRunError;
18
+ }
19
+ await this.runTaskSuccessHook(descriptor);
20
+ } catch (error) {
21
+ taskError = error;
22
+ this.logger.error(`Cron task ${descriptor.taskName} failed.`, error, 'CronLifecycleService');
23
+ }
24
+ await this.runTaskErrorHook(descriptor, taskError);
25
+ await this.runTaskAfterHook(descriptor);
26
+ return taskError;
27
+ }
28
+ async resolveTaskInvocation(descriptor) {
29
+ if (descriptor.callback) {
30
+ return {
31
+ callable: descriptor.callback,
32
+ instance: undefined
33
+ };
34
+ }
35
+ if (!descriptor.token || descriptor.methodKey === undefined || !descriptor.targetName || !descriptor.moduleName || !descriptor.methodName) {
36
+ this.logger.error(`Scheduling task ${descriptor.taskName} is missing invocation metadata and was skipped.`, undefined, 'CronLifecycleService');
37
+ return undefined;
38
+ }
39
+ let instance;
40
+ try {
41
+ instance = await this.runtimeContainer.resolve(descriptor.token);
42
+ } catch (error) {
43
+ this.logger.error(`Failed to resolve cron task target ${descriptor.targetName} from module ${descriptor.moduleName}.`, error, 'CronLifecycleService');
44
+ return undefined;
45
+ }
46
+ const value = instance[descriptor.methodKey];
47
+ if (typeof value !== 'function') {
48
+ this.logger.warn(`Cron method ${descriptor.targetName}.${descriptor.methodName} is not callable and was skipped.`, 'CronLifecycleService');
49
+ return undefined;
50
+ }
51
+ return {
52
+ callable: value,
53
+ instance
54
+ };
55
+ }
56
+ async runTaskBeforeHook(descriptor) {
57
+ if (!descriptor.beforeRun) {
58
+ return;
59
+ }
60
+ await Promise.resolve(descriptor.beforeRun());
61
+ }
62
+ async runTaskSuccessHook(descriptor) {
63
+ if (!descriptor.onSuccess) {
64
+ return;
65
+ }
66
+ await Promise.resolve(descriptor.onSuccess());
67
+ }
68
+ async runTaskErrorHook(descriptor, taskError) {
69
+ if (taskError && descriptor.onError) {
70
+ try {
71
+ await Promise.resolve(descriptor.onError(taskError));
72
+ } catch (hookError) {
73
+ this.logger.error(`Cron onError hook ${descriptor.taskName} failed.`, hookError, 'CronLifecycleService');
74
+ }
75
+ }
76
+ }
77
+ async runTaskAfterHook(descriptor) {
78
+ if (!descriptor.afterRun) {
79
+ return;
80
+ }
81
+ try {
82
+ await Promise.resolve(descriptor.afterRun());
83
+ } catch (hookError) {
84
+ this.logger.error(`Cron afterRun hook ${descriptor.taskName} failed.`, hookError, 'CronLifecycleService');
85
+ }
86
+ }
87
+ }
@@ -0,0 +1,7 @@
1
+ import type { Token } from '@fluojs/core';
2
+ import type { NormalizedCronModuleOptions, SchedulingRegistry } from './types.js';
3
+ /** Injection token for normalized cron module options used by {@link CronLifecycleService}. */
4
+ export declare const CRON_OPTIONS: Token<NormalizedCronModuleOptions>;
5
+ /** Injection token for the runtime scheduling registry exposed to application code. */
6
+ export declare const SCHEDULING_REGISTRY: Token<SchedulingRegistry>;
7
+ //# sourceMappingURL=tokens.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAE1C,OAAO,KAAK,EAAE,2BAA2B,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAElF,+FAA+F;AAC/F,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,2BAA2B,CAAmC,CAAC;AAChG,uFAAuF;AACvF,eAAO,MAAM,mBAAmB,EAAE,KAAK,CAAC,kBAAkB,CAA+C,CAAC"}
package/dist/tokens.js ADDED
@@ -0,0 +1,4 @@
1
+ /** Injection token for normalized cron module options used by {@link CronLifecycleService}. */
2
+ export const CRON_OPTIONS = Symbol.for('fluo.cron.options');
3
+ /** Injection token for the runtime scheduling registry exposed to application code. */
4
+ export const SCHEDULING_REGISTRY = Symbol.for('fluo.cron.scheduling-registry');
@@ -0,0 +1,206 @@
1
+ import type { MetadataPropertyKey, Token } from '@fluojs/core';
2
+ /** Supported task kinds handled by the scheduler runtime. */
3
+ export type SchedulingTaskKind = 'cron' | 'interval' | 'timeout';
4
+ /** Callback shape executed for one scheduled task invocation. */
5
+ export type SchedulingTaskCallback = () => void | Promise<void>;
6
+ /** Shared lifecycle hooks and lock settings supported by all scheduling APIs. */
7
+ export interface SchedulingTaskOptions {
8
+ afterRun?: () => void | Promise<void>;
9
+ beforeRun?: () => void | Promise<void>;
10
+ distributed?: boolean;
11
+ key?: string;
12
+ lockTtlMs?: number;
13
+ name?: string;
14
+ onError?: (error: unknown) => void | Promise<void>;
15
+ onSuccess?: () => void | Promise<void>;
16
+ }
17
+ /** Additional options available only for cron-expression tasks. */
18
+ export interface CronTaskOptions extends SchedulingTaskOptions {
19
+ timezone?: string;
20
+ }
21
+ /** Options for fixed-interval tasks registered with {@link Interval} or {@link SchedulingRegistry.addInterval}. */
22
+ export type IntervalTaskOptions = SchedulingTaskOptions;
23
+ /** Options for one-shot delayed tasks registered with {@link Timeout} or {@link SchedulingRegistry.addTimeout}. */
24
+ export type TimeoutTaskOptions = SchedulingTaskOptions;
25
+ /** Metadata captured for one method decorated with {@link Cron}. */
26
+ export interface CronTaskMetadata {
27
+ kind: 'cron';
28
+ expression: string;
29
+ options: CronTaskOptions;
30
+ }
31
+ /** Metadata captured for one method decorated with {@link Interval}. */
32
+ export interface IntervalTaskMetadata {
33
+ kind: 'interval';
34
+ ms: number;
35
+ options: IntervalTaskOptions;
36
+ }
37
+ /** Metadata captured for one method decorated with {@link Timeout}. */
38
+ export interface TimeoutTaskMetadata {
39
+ kind: 'timeout';
40
+ ms: number;
41
+ options: TimeoutTaskOptions;
42
+ }
43
+ /** Union of all decorator metadata shapes consumed by the scheduler runtime. */
44
+ export type SchedulingTaskMetadata = CronTaskMetadata | IntervalTaskMetadata | TimeoutTaskMetadata;
45
+ /** Distributed lock configuration for multi-instance scheduling. */
46
+ export interface CronDistributedOptions {
47
+ clientName?: string;
48
+ enabled?: boolean;
49
+ keyPrefix?: string;
50
+ lockTtlMs?: number;
51
+ ownerId?: string;
52
+ }
53
+ /** Shutdown drain configuration for active cron tasks. */
54
+ export interface CronShutdownOptions {
55
+ timeoutMs?: number;
56
+ }
57
+ /** Scheduler handle returned by the underlying cron engine. */
58
+ export interface CronScheduledJob {
59
+ stop(): void;
60
+ }
61
+ /** Options forwarded to the low-level cron scheduler implementation. */
62
+ export interface CronScheduleOptions {
63
+ name?: string;
64
+ protect?: boolean;
65
+ timezone?: string;
66
+ }
67
+ /** Adapter contract used to schedule cron expressions in the runtime. */
68
+ export type CronScheduler = (expression: string, options: CronScheduleOptions, callback: () => Promise<void>) => CronScheduledJob;
69
+ /** Module configuration accepted by {@link CronModule.forRoot}. */
70
+ export interface CronModuleOptions {
71
+ distributed?: boolean | CronDistributedOptions;
72
+ scheduler?: CronScheduler;
73
+ shutdown?: CronShutdownOptions;
74
+ }
75
+ /** Normalized scheduler configuration used internally by {@link CronLifecycleService}. */
76
+ export interface NormalizedCronModuleOptions {
77
+ distributed: {
78
+ clientName?: string;
79
+ enabled: boolean;
80
+ keyPrefix: string;
81
+ lockTtlMs: number;
82
+ ownerId: string;
83
+ };
84
+ scheduler: CronScheduler;
85
+ shutdown: {
86
+ timeoutMs: number;
87
+ };
88
+ }
89
+ /** Runtime descriptor for one discovered or dynamically registered task. */
90
+ export interface CronTaskDescriptor {
91
+ callback?: SchedulingTaskCallback;
92
+ kind: SchedulingTaskKind;
93
+ afterRun?: () => void | Promise<void>;
94
+ beforeRun?: () => void | Promise<void>;
95
+ distributed: boolean;
96
+ expression?: string;
97
+ ms?: number;
98
+ lockKey: string;
99
+ lockTtlMs: number;
100
+ methodKey?: MetadataPropertyKey;
101
+ methodName?: string;
102
+ moduleName?: string;
103
+ onError?: (error: unknown) => void | Promise<void>;
104
+ onSuccess?: () => void | Promise<void>;
105
+ taskName: string;
106
+ timezone?: string;
107
+ targetName?: string;
108
+ token?: Token;
109
+ }
110
+ /** Read-only task descriptor exposed by the scheduling registry. */
111
+ export interface SchedulingTaskDescriptor {
112
+ enabled: boolean;
113
+ kind: SchedulingTaskKind;
114
+ name: string;
115
+ source: 'decorator' | 'dynamic';
116
+ distributed: boolean;
117
+ lockKey: string;
118
+ lockTtlMs: number;
119
+ expression?: string;
120
+ ms?: number;
121
+ timezone?: string;
122
+ moduleName?: string;
123
+ targetName?: string;
124
+ methodName?: string;
125
+ }
126
+ /**
127
+ * Programmatic registry for adding, inspecting, and mutating scheduled tasks at runtime.
128
+ *
129
+ * @example
130
+ * ```ts
131
+ * registry.addCron('cleanup', '0 * * * *', async () => {
132
+ * await cleanupExpiredSessions();
133
+ * });
134
+ * ```
135
+ */
136
+ export interface SchedulingRegistry {
137
+ /**
138
+ * Adds a cron-expression task to the runtime registry.
139
+ *
140
+ * @param name Stable task name used for lookup and distributed lock keys.
141
+ * @param expression Cron expression validated before registration.
142
+ * @param callback Task body executed on each schedule tick.
143
+ * @param options Optional task hooks, naming overrides, and distributed lock controls.
144
+ */
145
+ addCron(name: string, expression: string, callback: SchedulingTaskCallback, options?: CronTaskOptions): void;
146
+ /**
147
+ * Adds a fixed-interval task to the runtime registry.
148
+ *
149
+ * @param name Stable task name used for lookup and distributed lock keys.
150
+ * @param ms Positive interval in milliseconds.
151
+ * @param callback Task body executed on each interval tick.
152
+ * @param options Optional task hooks, naming overrides, and distributed lock controls.
153
+ */
154
+ addInterval(name: string, ms: number, callback: SchedulingTaskCallback, options?: IntervalTaskOptions): void;
155
+ /**
156
+ * Adds a one-shot delayed task to the runtime registry.
157
+ *
158
+ * @param name Stable task name used for lookup and distributed lock keys.
159
+ * @param ms Positive delay in milliseconds before the callback runs once.
160
+ * @param callback Task body executed after the delay elapses.
161
+ * @param options Optional task hooks, naming overrides, and distributed lock controls.
162
+ */
163
+ addTimeout(name: string, ms: number, callback: SchedulingTaskCallback, options?: TimeoutTaskOptions): void;
164
+ /**
165
+ * Removes one registered task from the runtime registry.
166
+ *
167
+ * @param name Task name to remove.
168
+ * @returns `true` when a task existed and was removed.
169
+ */
170
+ remove(name: string): boolean;
171
+ /**
172
+ * Re-enables a previously disabled task.
173
+ *
174
+ * @param name Task name to enable.
175
+ * @returns `true` when the task exists after the operation.
176
+ */
177
+ enable(name: string): boolean;
178
+ /**
179
+ * Disables a task without deleting its descriptor.
180
+ *
181
+ * @param name Task name to disable.
182
+ * @returns `true` when the task exists after the operation.
183
+ */
184
+ disable(name: string): boolean;
185
+ /**
186
+ * Reads one task descriptor by name.
187
+ *
188
+ * @param name Task name to inspect.
189
+ * @returns The current descriptor, or `undefined` when no task is registered.
190
+ */
191
+ get(name: string): SchedulingTaskDescriptor | undefined;
192
+ /**
193
+ * Lists all registered tasks.
194
+ *
195
+ * @returns All known task descriptors, including decorator-discovered and dynamic tasks.
196
+ */
197
+ getAll(): SchedulingTaskDescriptor[];
198
+ /**
199
+ * Replaces the cron expression for an existing cron task.
200
+ *
201
+ * @param name Task name to update.
202
+ * @param expression New cron expression validated before rescheduling.
203
+ */
204
+ updateCronExpression(name: string, expression: string): void;
205
+ }
206
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "@fluojs/cron",
3
+ "description": "Decorator-based task scheduling for Fluo with cron, interval, and timeout triggers and optional distributed locking.",
4
+ "keywords": [
5
+ "fluo",
6
+ "cron",
7
+ "scheduler",
8
+ "interval",
9
+ "timeout",
10
+ "distributed-lock"
11
+ ],
12
+ "version": "1.0.0-beta.1",
13
+ "private": false,
14
+ "license": "MIT",
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "https://github.com/fluojs/fluo.git",
18
+ "directory": "packages/cron"
19
+ },
20
+ "engines": {
21
+ "node": ">=20.0.0"
22
+ },
23
+ "publishConfig": {
24
+ "access": "public"
25
+ },
26
+ "type": "module",
27
+ "exports": {
28
+ ".": {
29
+ "types": "./dist/index.d.ts",
30
+ "import": "./dist/index.js"
31
+ }
32
+ },
33
+ "main": "./dist/index.js",
34
+ "types": "./dist/index.d.ts",
35
+ "files": [
36
+ "dist"
37
+ ],
38
+ "dependencies": {
39
+ "croner": "^8.1.2",
40
+ "@fluojs/core": "^1.0.0-beta.1",
41
+ "@fluojs/redis": "^1.0.0-beta.1",
42
+ "@fluojs/di": "^1.0.0-beta.1",
43
+ "@fluojs/runtime": "^1.0.0-beta.1"
44
+ },
45
+ "devDependencies": {
46
+ "vitest": "^3.2.4"
47
+ },
48
+ "scripts": {
49
+ "prebuild": "node ../../tooling/scripts/clean-dist.mjs",
50
+ "build": "pnpm exec babel src --extensions .ts --ignore 'src/**/*.test.ts' --out-dir dist --config-file ../../tooling/babel/babel.config.cjs && pnpm exec tsc -p tsconfig.build.json",
51
+ "typecheck": "pnpm exec tsc -p tsconfig.json --noEmit",
52
+ "test": "pnpm exec vitest run -c vitest.config.ts",
53
+ "test:watch": "pnpm exec vitest -c vitest.config.ts"
54
+ }
55
+ }