@memberjunction/server 2.106.0 → 2.107.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.
@@ -0,0 +1,105 @@
1
+ import { LogError, LogStatus } from '@memberjunction/core';
2
+ import { UserCache } from '@memberjunction/sqlserver-dataprovider';
3
+ import { SchedulingEngine } from '@memberjunction/scheduling-engine';
4
+ export class ScheduledJobsService {
5
+ engine;
6
+ systemUser = null;
7
+ isRunning = false;
8
+ config;
9
+ constructor(config) {
10
+ this.config = config;
11
+ this.engine = SchedulingEngine.Instance;
12
+ }
13
+ async Initialize() {
14
+ if (!this.config.enabled) {
15
+ LogStatus('[ScheduledJobsService] Scheduled jobs are disabled in configuration');
16
+ return;
17
+ }
18
+ try {
19
+ this.systemUser = await this.getSystemUser();
20
+ if (!this.systemUser) {
21
+ throw new Error(`System user not found with email: ${this.config.systemUserEmail}`);
22
+ }
23
+ await this.engine.Config(false, this.systemUser);
24
+ }
25
+ catch (error) {
26
+ LogError('[ScheduledJobsService] Failed to initialize', undefined, error);
27
+ throw error;
28
+ }
29
+ }
30
+ async Start() {
31
+ if (!this.config.enabled) {
32
+ return;
33
+ }
34
+ if (this.isRunning) {
35
+ LogStatus('[ScheduledJobsService] Already running');
36
+ return;
37
+ }
38
+ if (!this.systemUser) {
39
+ throw new Error('Service not initialized - call Initialize() first');
40
+ }
41
+ try {
42
+ this.engine.StartPolling(this.systemUser);
43
+ this.isRunning = true;
44
+ const jobCount = this.engine.ScheduledJobs.length;
45
+ if (jobCount === 0) {
46
+ console.log(`📅 Scheduled Jobs: No active jobs, polling suspended (will auto-start when jobs are added)`);
47
+ }
48
+ else {
49
+ const interval = this.engine.ActivePollingInterval;
50
+ if (interval !== null) {
51
+ const intervalDisplay = interval >= 60000
52
+ ? `${Math.round(interval / 60000)} minute(s)`
53
+ : `${Math.round(interval / 1000)} second(s)`;
54
+ console.log(`📅 Scheduled Jobs: ${jobCount} active job(s), polling every ${intervalDisplay}`);
55
+ }
56
+ else {
57
+ console.log(`📅 Scheduled Jobs: ${jobCount} active job(s), polling interval not set`);
58
+ }
59
+ }
60
+ }
61
+ catch (error) {
62
+ LogError('[ScheduledJobsService] Failed to start polling', undefined, error);
63
+ throw error;
64
+ }
65
+ }
66
+ async Stop() {
67
+ if (!this.isRunning) {
68
+ return;
69
+ }
70
+ try {
71
+ LogStatus('[ScheduledJobsService] Stopping scheduled job polling');
72
+ this.engine.StopPolling();
73
+ this.isRunning = false;
74
+ LogStatus('[ScheduledJobsService] Polling stopped successfully');
75
+ }
76
+ catch (error) {
77
+ LogError('[ScheduledJobsService] Error stopping polling', undefined, error);
78
+ throw error;
79
+ }
80
+ }
81
+ async getSystemUser() {
82
+ const systemUserEmail = this.config.systemUserEmail;
83
+ const user = UserCache.Users.find(u => u.Email?.toLowerCase() === systemUserEmail.toLowerCase());
84
+ if (user) {
85
+ return user;
86
+ }
87
+ LogError(`[ScheduledJobsService] System user not found with email: ${systemUserEmail}`);
88
+ return null;
89
+ }
90
+ GetStatus() {
91
+ return {
92
+ enabled: this.config.enabled,
93
+ running: this.isRunning,
94
+ activeJobs: this.engine?.ScheduledJobs?.length || 0,
95
+ pollingInterval: this.engine?.ActivePollingInterval || 0
96
+ };
97
+ }
98
+ get IsEnabled() {
99
+ return this.config.enabled;
100
+ }
101
+ get IsRunning() {
102
+ return this.isRunning;
103
+ }
104
+ }
105
+ //# sourceMappingURL=ScheduledJobsService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ScheduledJobsService.js","sourceRoot":"","sources":["../../src/services/ScheduledJobsService.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/server",
3
- "version": "2.106.0",
3
+ "version": "2.107.0",
4
4
  "description": "MemberJunction: This project provides API access via GraphQL to the common data store.",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./src/index.ts",
@@ -22,37 +22,41 @@
22
22
  "dependencies": {
23
23
  "@apollo/server": "^4.9.1",
24
24
  "@graphql-tools/utils": "^10.0.1",
25
- "@memberjunction/actions": "2.106.0",
26
- "@memberjunction/ai": "2.106.0",
27
- "@memberjunction/ai-core-plus": "2.106.0",
28
- "@memberjunction/ai-agents": "2.106.0",
29
- "@memberjunction/ai-provider-bundle": "2.106.0",
30
- "@memberjunction/aiengine": "2.106.0",
31
- "@memberjunction/ai-prompts": "2.106.0",
32
- "@memberjunction/ai-agent-manager-actions": "2.106.0",
33
- "@memberjunction/ai-vectors-pinecone": "2.106.0",
25
+ "@memberjunction/actions": "2.107.0",
26
+ "@memberjunction/ai": "2.107.0",
27
+ "@memberjunction/ai-core-plus": "2.107.0",
28
+ "@memberjunction/ai-agents": "2.107.0",
29
+ "@memberjunction/ai-provider-bundle": "2.107.0",
30
+ "@memberjunction/aiengine": "2.107.0",
31
+ "@memberjunction/ai-prompts": "2.107.0",
32
+ "@memberjunction/ai-agent-manager-actions": "2.107.0",
33
+ "@memberjunction/ai-vectors-pinecone": "2.107.0",
34
34
  "@memberjunction/core": "2.100.3",
35
- "@memberjunction/core-actions": "2.106.0",
36
- "@memberjunction/actions-apollo": "2.106.0",
37
- "@memberjunction/actions-bizapps-accounting": "2.106.0",
38
- "@memberjunction/actions-bizapps-crm": "2.106.0",
39
- "@memberjunction/actions-bizapps-lms": "2.106.0",
40
- "@memberjunction/actions-bizapps-social": "2.106.0",
41
- "@memberjunction/component-registry-client-sdk": "2.106.0",
42
- "@memberjunction/core-entities": "2.106.0",
43
- "@memberjunction/core-entities-server": "2.106.0",
44
- "@memberjunction/data-context": "2.106.0",
45
- "@memberjunction/data-context-server": "2.106.0",
46
- "@memberjunction/doc-utils": "2.106.0",
47
- "@memberjunction/entity-communications-server": "2.106.0",
48
- "@memberjunction/external-change-detection": "2.106.0",
35
+ "@memberjunction/core-actions": "2.107.0",
36
+ "@memberjunction/actions-apollo": "2.107.0",
37
+ "@memberjunction/actions-bizapps-accounting": "2.107.0",
38
+ "@memberjunction/actions-bizapps-crm": "2.107.0",
39
+ "@memberjunction/actions-bizapps-lms": "2.107.0",
40
+ "@memberjunction/actions-bizapps-social": "2.107.0",
41
+ "@memberjunction/component-registry-client-sdk": "2.107.0",
42
+ "@memberjunction/core-entities": "2.107.0",
43
+ "@memberjunction/core-entities-server": "2.107.0",
44
+ "@memberjunction/data-context": "2.107.0",
45
+ "@memberjunction/data-context-server": "2.107.0",
46
+ "@memberjunction/doc-utils": "2.107.0",
47
+ "@memberjunction/entity-communications-server": "2.107.0",
48
+ "@memberjunction/external-change-detection": "2.107.0",
49
49
  "@memberjunction/global": "2.100.3",
50
- "@memberjunction/graphql-dataprovider": "2.106.0",
51
- "@memberjunction/queue": "2.106.0",
52
- "@memberjunction/skip-types": "2.106.0",
53
- "@memberjunction/sqlserver-dataprovider": "2.106.0",
54
- "@memberjunction/storage": "2.106.0",
55
- "@memberjunction/templates": "2.106.0",
50
+ "@memberjunction/graphql-dataprovider": "2.107.0",
51
+ "@memberjunction/queue": "2.107.0",
52
+ "@memberjunction/scheduling-base-types": "2.107.0",
53
+ "@memberjunction/scheduling-engine-base": "2.107.0",
54
+ "@memberjunction/scheduling-engine": "2.107.0",
55
+ "@memberjunction/scheduling-actions": "2.107.0",
56
+ "@memberjunction/skip-types": "2.107.0",
57
+ "@memberjunction/sqlserver-dataprovider": "2.107.0",
58
+ "@memberjunction/storage": "2.107.0",
59
+ "@memberjunction/templates": "2.107.0",
56
60
  "@types/compression": "^1.7.5",
57
61
  "@types/cors": "^2.8.13",
58
62
  "@types/jsonwebtoken": "9.0.6",
package/src/config.ts CHANGED
@@ -130,6 +130,14 @@ const componentRegistrySchema = z.object({
130
130
  headers: z.record(z.string()).optional(),
131
131
  }).passthrough(); // Allow additional fields
132
132
 
133
+ const scheduledJobsSchema = z.object({
134
+ enabled: z.boolean().optional().default(false),
135
+ systemUserEmail: z.string().optional().default('system@memberjunction.org'),
136
+ maxConcurrentJobs: z.number().optional().default(5),
137
+ defaultLockTimeout: z.number().optional().default(600000), // 10 minutes in ms
138
+ staleLockCleanupInterval: z.number().optional().default(300000), // 5 minutes in ms
139
+ });
140
+
133
141
  const configInfoSchema = z.object({
134
142
  userHandling: userHandlingInfoSchema,
135
143
  databaseSettings: databaseSettingsInfoSchema,
@@ -139,6 +147,7 @@ const configInfoSchema = z.object({
139
147
  sqlLogging: sqlLoggingSchema.optional(),
140
148
  authProviders: z.array(authProviderSchema).optional(),
141
149
  componentRegistries: z.array(componentRegistrySchema).optional(),
150
+ scheduledJobs: scheduledJobsSchema.optional().default({}),
142
151
 
143
152
  apiKey: z.string().optional(),
144
153
  baseUrl: z.string().default('http://localhost'),
@@ -180,6 +189,7 @@ export type SqlLoggingOptions = z.infer<typeof sqlLoggingOptionsSchema>;
180
189
  export type SqlLoggingInfo = z.infer<typeof sqlLoggingSchema>;
181
190
  export type AuthProviderConfig = z.infer<typeof authProviderSchema>;
182
191
  export type ComponentRegistryConfig = z.infer<typeof componentRegistrySchema>;
192
+ export type ScheduledJobsConfig = z.infer<typeof scheduledJobsSchema>;
183
193
  export type ConfigInfo = z.infer<typeof configInfoSchema>;
184
194
 
185
195
  export const configInfo: ConfigInfo = loadConfig();