Compare commits

..

3 Commits

Author SHA1 Message Date
Bas
b3de54b953 Merge pull request #20 from xtr-dev/dev
Simplify job system architecture
2025-09-13 20:16:10 +02:00
186c340d96 Bump package version to 0.1.4 in package.json. 2025-09-13 20:14:59 +02:00
08b4d49019 Simplify job system architecture
- Replace createMailingJobs() function with static mailingJobs array
- Remove complex initialization dependencies and function wrappers
- Jobs now get MailingService from payload context instead of factory injection
- Fix PayloadCMS task handler return types to use proper {output: {}} format
- Eliminate potential initialization race conditions
- Cleaner, more straightforward job registration process

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-13 20:12:14 +02:00
5 changed files with 43 additions and 47 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "@xtr-dev/payload-mailing",
"version": "0.1.3",
"version": "0.1.4",
"description": "Template-based email system with scheduling and job processing for PayloadCMS",
"type": "module",
"main": "dist/index.js",

View File

@@ -12,7 +12,7 @@ export { default as EmailTemplates, createEmailTemplatesCollection } from './col
export { default as Emails } from './collections/Emails.js'
// Jobs (includes the send email task)
export { createMailingJobs, sendEmailJob } from './jobs/index.js'
export { mailingJobs, sendEmailJob } from './jobs/index.js'
export type { SendEmailTaskInput } from './jobs/sendEmailTask.js'
// Utility functions for developers

View File

@@ -2,21 +2,34 @@ import { processEmailsJob, ProcessEmailsJobData } from './processEmailsJob.js'
import { sendEmailJob } from './sendEmailTask.js'
import { MailingService } from '../services/MailingService.js'
export const createMailingJobs = (mailingService: MailingService): any[] => {
return [
export const mailingJobs = [
{
slug: 'processEmails',
handler: async ({ job, req }: { job: any; req: any }) => {
return processEmailsJob(
// Get mailing context from payload
const payload = (req as any).payload
const mailingContext = payload.mailing
if (!mailingContext) {
throw new Error('Mailing plugin not properly initialized')
}
// Use the existing mailing service from context
await processEmailsJob(
job as { data: ProcessEmailsJobData },
{ req, mailingService }
{ req, mailingService: mailingContext.service }
)
return {
output: {
success: true,
message: 'Email queue processing completed successfully'
}
}
},
interfaceName: 'ProcessEmailsJob',
},
sendEmailJob,
]
}
]
export * from './processEmailsJob.js'
export * from './sendEmailTask.js'

View File

@@ -208,6 +208,7 @@ export const sendEmailJob = {
})
return {
output: {
success: true,
emailId: email.id,
message: `Email queued successfully with ID: ${email.id}`,
@@ -217,16 +218,12 @@ export const sendEmailJob = {
recipients: emailData.to?.length || 0,
scheduledAt: emailData.scheduledAt || null
}
}
} catch (error) {
const errorMessage = error instanceof Error ? error.message : 'Unknown error'
return {
success: false,
error: errorMessage,
templateSlug: taskInput.templateSlug,
message: `Failed to queue email: ${errorMessage}`
}
throw new Error(`Failed to queue email: ${errorMessage}`)
}
}
}

View File

@@ -3,7 +3,7 @@ import { MailingPluginConfig, MailingContext } from './types/index.js'
import { MailingService } from './services/MailingService.js'
import { createEmailTemplatesCollection } from './collections/EmailTemplates.js'
import Emails from './collections/Emails.js'
import { createMailingJobs, scheduleEmailsJob } from './jobs/index.js'
import { mailingJobs, scheduleEmailsJob } from './jobs/index.js'
export const mailingPlugin = (pluginConfig: MailingPluginConfig) => (config: Config): Config => {
@@ -14,14 +14,6 @@ export const mailingPlugin = (pluginConfig: MailingPluginConfig) => (config: Con
throw new Error('Invalid queue configuration: queue must be a non-empty string')
}
// Create a factory function that will provide the mailing service once initialized
const getMailingService = () => {
if (!mailingService) {
throw new Error('MailingService not yet initialized - this should only be called after plugin initialization')
}
return mailingService
}
let mailingService: MailingService
// Handle templates collection configuration
const templatesConfig = pluginConfig.collections?.templates
@@ -93,7 +85,7 @@ export const mailingPlugin = (pluginConfig: MailingPluginConfig) => (config: Con
...(config.jobs || {}),
tasks: [
...(config.jobs?.tasks || []),
// Jobs will be properly added after initialization
...mailingJobs,
],
},
onInit: async (payload: any) => {
@@ -102,13 +94,7 @@ export const mailingPlugin = (pluginConfig: MailingPluginConfig) => (config: Con
}
// Initialize mailing service with proper payload instance
mailingService = new MailingService(payload, pluginConfig)
// Add mailing jobs to payload's job system
const mailingJobs = createMailingJobs(mailingService)
mailingJobs.forEach(job => {
payload.jobs.tasks.push(job)
})
const mailingService = new MailingService(payload, pluginConfig)
// Add mailing context to payload for developer access
;(payload as any).mailing = {