@spfn/notification 0.1.0-beta.16 → 0.1.0-beta.18
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.
- package/README.md +59 -4
- package/dist/server.d.ts +141 -24
- package/dist/server.js +1313 -833
- package/dist/server.js.map +1 -1
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -22,8 +22,8 @@ pnpm add @spfn/notification
|
|
|
22
22
|
Install providers as needed:
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
|
-
# For AWS SES (Email)
|
|
26
|
-
pnpm add @aws-sdk/client-
|
|
25
|
+
# For AWS SES v2 (Email)
|
|
26
|
+
pnpm add @aws-sdk/client-sesv2
|
|
27
27
|
|
|
28
28
|
# For AWS SNS (SMS)
|
|
29
29
|
pnpm add @aws-sdk/client-sns
|
|
@@ -131,11 +131,16 @@ await sendEmail({
|
|
|
131
131
|
html: '<h1>HTML content</h1>',
|
|
132
132
|
});
|
|
133
133
|
|
|
134
|
-
// Bulk send
|
|
134
|
+
// Bulk send (in-process, parallel)
|
|
135
135
|
await sendEmailBulk([
|
|
136
136
|
{ to: 'user1@example.com', template: 'welcome', data: { name: 'John' } },
|
|
137
137
|
{ to: 'user2@example.com', template: 'welcome', data: { name: 'Jane' } },
|
|
138
|
-
]);
|
|
138
|
+
], { concurrency: 20 });
|
|
139
|
+
|
|
140
|
+
// Bulk send (distributed across instances via pg-boss)
|
|
141
|
+
const result = await sendEmailBulk(items, { distributed: true });
|
|
142
|
+
// result.batchId — UUID for tracking this batch
|
|
143
|
+
// Actual sending happens in background via pg-boss workers
|
|
139
144
|
```
|
|
140
145
|
|
|
141
146
|
### SMS
|
|
@@ -183,6 +188,47 @@ import { cancelNotification } from '@spfn/notification/server';
|
|
|
183
188
|
await cancelNotification(result.notificationId);
|
|
184
189
|
```
|
|
185
190
|
|
|
191
|
+
## Bulk Sending
|
|
192
|
+
|
|
193
|
+
All channels support bulk sending with two modes:
|
|
194
|
+
|
|
195
|
+
### In-Process Mode (default)
|
|
196
|
+
|
|
197
|
+
Sends all items in the current process with concurrency control.
|
|
198
|
+
Suitable for single-instance deployments or smaller batches.
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
import { sendEmailBulk, sendSMSBulk, sendSlackBulk } from '@spfn/notification/server';
|
|
202
|
+
|
|
203
|
+
const result = await sendEmailBulk(items, { concurrency: 20 });
|
|
204
|
+
// result.results — SendResult[] in same order as input
|
|
205
|
+
// result.successCount / result.failureCount
|
|
206
|
+
// result.batchId — UUID for this batch
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Distributed Mode
|
|
210
|
+
|
|
211
|
+
Enqueues items to pg-boss for processing across multiple instances.
|
|
212
|
+
Each instance's worker fetches 50 items at a time and processes them in parallel.
|
|
213
|
+
Failed items are individually retried by pg-boss.
|
|
214
|
+
|
|
215
|
+
```typescript
|
|
216
|
+
const result = await sendEmailBulk(items, { distributed: true });
|
|
217
|
+
// Returns immediately with pending results
|
|
218
|
+
// result.results[i].messageId === 'pending:{batchId}'
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
**Distributed mode flow:**
|
|
222
|
+
1. Validates and renders templates
|
|
223
|
+
2. Batch inserts notification records (single query)
|
|
224
|
+
3. Applies tracking (email only)
|
|
225
|
+
4. Bulk inserts pg-boss jobs via `sendBatch()`
|
|
226
|
+
5. Returns immediately — workers process in background
|
|
227
|
+
|
|
228
|
+
**Requirements:**
|
|
229
|
+
- `notificationJobRouter` must be registered (see Job Router Setup below)
|
|
230
|
+
- pg-boss must be initialized
|
|
231
|
+
|
|
186
232
|
### Job Router Setup
|
|
187
233
|
|
|
188
234
|
Register the notification job router with your server:
|
|
@@ -493,16 +539,22 @@ export {
|
|
|
493
539
|
sendEmail,
|
|
494
540
|
sendEmailBulk,
|
|
495
541
|
registerEmailProvider,
|
|
542
|
+
type BulkEmailResult,
|
|
543
|
+
type BulkEmailOptions,
|
|
496
544
|
|
|
497
545
|
// SMS
|
|
498
546
|
sendSMS,
|
|
499
547
|
sendSMSBulk,
|
|
500
548
|
registerSMSProvider,
|
|
549
|
+
type BulkSMSResult,
|
|
550
|
+
type BulkSMSOptions,
|
|
501
551
|
|
|
502
552
|
// Slack
|
|
503
553
|
sendSlack,
|
|
504
554
|
sendSlackBulk,
|
|
505
555
|
registerSlackProvider,
|
|
556
|
+
type BulkSlackResult,
|
|
557
|
+
type BulkSlackOptions,
|
|
506
558
|
|
|
507
559
|
// Scheduling
|
|
508
560
|
scheduleEmail,
|
|
@@ -528,6 +580,9 @@ export {
|
|
|
528
580
|
|
|
529
581
|
// Jobs
|
|
530
582
|
notificationJobRouter,
|
|
583
|
+
sendBulkEmailItemJob,
|
|
584
|
+
sendBulkSmsItemJob,
|
|
585
|
+
sendBulkSlackItemJob,
|
|
531
586
|
};
|
|
532
587
|
```
|
|
533
588
|
|
package/dist/server.d.ts
CHANGED
|
@@ -20,13 +20,37 @@ declare function registerEmailProvider(provider: EmailProvider): void;
|
|
|
20
20
|
*/
|
|
21
21
|
declare function sendEmail(params: SendEmailParams): Promise<SendResult>;
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
23
|
+
* Bulk email result
|
|
24
24
|
*/
|
|
25
|
-
|
|
25
|
+
interface BulkEmailResult {
|
|
26
26
|
results: SendResult[];
|
|
27
27
|
successCount: number;
|
|
28
28
|
failureCount: number;
|
|
29
|
-
|
|
29
|
+
batchId: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Bulk email options
|
|
33
|
+
*/
|
|
34
|
+
interface BulkEmailOptions {
|
|
35
|
+
/**
|
|
36
|
+
* Max parallel sends when processing in-process (default: 10)
|
|
37
|
+
*/
|
|
38
|
+
concurrency?: number;
|
|
39
|
+
/**
|
|
40
|
+
* When true, enqueue to pg-boss for distributed processing across instances.
|
|
41
|
+
* Returns immediately with pending results — actual sending happens in background.
|
|
42
|
+
* Requires notificationJobRouter to be registered.
|
|
43
|
+
* @default false
|
|
44
|
+
*/
|
|
45
|
+
distributed?: boolean;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Send bulk emails with batch DB insert and concurrent sending.
|
|
49
|
+
*
|
|
50
|
+
* @param items - Email items to send
|
|
51
|
+
* @param options - concurrency, distributed
|
|
52
|
+
*/
|
|
53
|
+
declare function sendEmailBulk(items: SendEmailParams[], options?: BulkEmailOptions): Promise<BulkEmailResult>;
|
|
30
54
|
|
|
31
55
|
/**
|
|
32
56
|
* @spfn/notification - SMS Channel
|
|
@@ -41,13 +65,28 @@ declare function registerSMSProvider(provider: SMSProvider): void;
|
|
|
41
65
|
*/
|
|
42
66
|
declare function sendSMS(params: SendSMSParams): Promise<SendResult>;
|
|
43
67
|
/**
|
|
44
|
-
*
|
|
68
|
+
* Bulk SMS result
|
|
45
69
|
*/
|
|
46
|
-
|
|
70
|
+
interface BulkSMSResult {
|
|
47
71
|
results: SendResult[];
|
|
48
72
|
successCount: number;
|
|
49
73
|
failureCount: number;
|
|
50
|
-
|
|
74
|
+
batchId: string;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Bulk SMS options
|
|
78
|
+
*/
|
|
79
|
+
interface BulkSMSOptions {
|
|
80
|
+
concurrency?: number;
|
|
81
|
+
distributed?: boolean;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Send bulk SMS with batch DB insert and concurrent sending.
|
|
85
|
+
*
|
|
86
|
+
* @param items - SMS items to send
|
|
87
|
+
* @param options - concurrency, distributed
|
|
88
|
+
*/
|
|
89
|
+
declare function sendSMSBulk(items: SendSMSParams[], options?: BulkSMSOptions): Promise<BulkSMSResult>;
|
|
51
90
|
|
|
52
91
|
/**
|
|
53
92
|
* @spfn/notification - Slack Channel
|
|
@@ -62,13 +101,28 @@ declare function registerSlackProvider(provider: SlackProvider): void;
|
|
|
62
101
|
*/
|
|
63
102
|
declare function sendSlack(params: SendSlackParams): Promise<SendResult>;
|
|
64
103
|
/**
|
|
65
|
-
*
|
|
104
|
+
* Bulk Slack result
|
|
66
105
|
*/
|
|
67
|
-
|
|
106
|
+
interface BulkSlackResult {
|
|
68
107
|
results: SendResult[];
|
|
69
108
|
successCount: number;
|
|
70
109
|
failureCount: number;
|
|
71
|
-
|
|
110
|
+
batchId: string;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Bulk Slack options
|
|
114
|
+
*/
|
|
115
|
+
interface BulkSlackOptions {
|
|
116
|
+
concurrency?: number;
|
|
117
|
+
distributed?: boolean;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Send bulk Slack messages with batch DB insert and concurrent sending.
|
|
121
|
+
*
|
|
122
|
+
* @param items - Slack items to send
|
|
123
|
+
* @param options - concurrency, distributed
|
|
124
|
+
*/
|
|
125
|
+
declare function sendSlackBulk(items: SendSlackParams[], options?: BulkSlackOptions): Promise<BulkSlackResult>;
|
|
72
126
|
|
|
73
127
|
/**
|
|
74
128
|
* @spfn/notification - Schedule Service
|
|
@@ -807,17 +861,17 @@ declare function cancelNotificationsByReference(referenceType: string, reference
|
|
|
807
861
|
* Scheduled email sending job
|
|
808
862
|
*/
|
|
809
863
|
declare const sendScheduledEmailJob: _spfn_core_job.JobDef<{
|
|
810
|
-
from?: string | undefined;
|
|
811
|
-
subject?: string | undefined;
|
|
812
|
-
html?: string | undefined;
|
|
813
|
-
text?: string | undefined;
|
|
814
864
|
data?: {
|
|
815
865
|
[x: string]: unknown;
|
|
816
866
|
} | undefined;
|
|
817
|
-
|
|
867
|
+
subject?: string | undefined;
|
|
868
|
+
from?: string | undefined;
|
|
869
|
+
html?: string | undefined;
|
|
870
|
+
text?: string | undefined;
|
|
818
871
|
replyTo?: string | undefined;
|
|
819
|
-
|
|
872
|
+
template?: string | undefined;
|
|
820
873
|
notificationId: number;
|
|
874
|
+
to: string | string[];
|
|
821
875
|
}, void>;
|
|
822
876
|
|
|
823
877
|
/**
|
|
@@ -827,13 +881,56 @@ declare const sendScheduledEmailJob: _spfn_core_job.JobDef<{
|
|
|
827
881
|
* Scheduled SMS sending job
|
|
828
882
|
*/
|
|
829
883
|
declare const sendScheduledSmsJob: _spfn_core_job.JobDef<{
|
|
830
|
-
message?: string | undefined;
|
|
831
884
|
data?: {
|
|
832
885
|
[x: string]: unknown;
|
|
833
886
|
} | undefined;
|
|
887
|
+
message?: string | undefined;
|
|
834
888
|
template?: string | undefined;
|
|
889
|
+
notificationId: number;
|
|
835
890
|
to: string | string[];
|
|
891
|
+
}, void>;
|
|
892
|
+
|
|
893
|
+
/**
|
|
894
|
+
* @spfn/notification - Bulk Email Item Job
|
|
895
|
+
*
|
|
896
|
+
* Processes a single email item from a distributed bulk send.
|
|
897
|
+
* Notification record and tracking are already applied by sendEmailBulk().
|
|
898
|
+
* This job just sends via provider and updates history.
|
|
899
|
+
*
|
|
900
|
+
* Uses batchSize so pg-boss workers fetch multiple items at once
|
|
901
|
+
* and process them in parallel across instances.
|
|
902
|
+
*/
|
|
903
|
+
declare const sendBulkEmailItemJob: _spfn_core_job.JobDef<{
|
|
904
|
+
html?: string | undefined;
|
|
905
|
+
text?: string | undefined;
|
|
906
|
+
replyTo?: string | undefined;
|
|
907
|
+
subject: string;
|
|
908
|
+
notificationId: number;
|
|
909
|
+
to: string[];
|
|
910
|
+
from: string;
|
|
911
|
+
}, void>;
|
|
912
|
+
|
|
913
|
+
/**
|
|
914
|
+
* @spfn/notification - Bulk SMS Item Job
|
|
915
|
+
*
|
|
916
|
+
* Processes a single SMS item from a distributed bulk send.
|
|
917
|
+
*/
|
|
918
|
+
declare const sendBulkSmsItemJob: _spfn_core_job.JobDef<{
|
|
836
919
|
notificationId: number;
|
|
920
|
+
to: string;
|
|
921
|
+
message: string;
|
|
922
|
+
}, void>;
|
|
923
|
+
|
|
924
|
+
/**
|
|
925
|
+
* @spfn/notification - Bulk Slack Item Job
|
|
926
|
+
*
|
|
927
|
+
* Processes a single Slack item from a distributed bulk send.
|
|
928
|
+
*/
|
|
929
|
+
declare const sendBulkSlackItemJob: _spfn_core_job.JobDef<{
|
|
930
|
+
text?: string | undefined;
|
|
931
|
+
blocks?: unknown[] | undefined;
|
|
932
|
+
notificationId: number;
|
|
933
|
+
webhookUrl: string;
|
|
837
934
|
}, void>;
|
|
838
935
|
|
|
839
936
|
/**
|
|
@@ -858,26 +955,46 @@ declare const sendScheduledSmsJob: _spfn_core_job.JobDef<{
|
|
|
858
955
|
*/
|
|
859
956
|
declare const notificationJobRouter: _spfn_core_job.JobRouter<{
|
|
860
957
|
sendScheduledEmail: _spfn_core_job.JobDef<{
|
|
861
|
-
from?: string | undefined;
|
|
862
|
-
subject?: string | undefined;
|
|
863
|
-
html?: string | undefined;
|
|
864
|
-
text?: string | undefined;
|
|
865
958
|
data?: {
|
|
866
959
|
[x: string]: unknown;
|
|
867
960
|
} | undefined;
|
|
868
|
-
|
|
961
|
+
subject?: string | undefined;
|
|
962
|
+
from?: string | undefined;
|
|
963
|
+
html?: string | undefined;
|
|
964
|
+
text?: string | undefined;
|
|
869
965
|
replyTo?: string | undefined;
|
|
870
|
-
|
|
966
|
+
template?: string | undefined;
|
|
871
967
|
notificationId: number;
|
|
968
|
+
to: string | string[];
|
|
872
969
|
}, void>;
|
|
873
970
|
sendScheduledSms: _spfn_core_job.JobDef<{
|
|
874
|
-
message?: string | undefined;
|
|
875
971
|
data?: {
|
|
876
972
|
[x: string]: unknown;
|
|
877
973
|
} | undefined;
|
|
974
|
+
message?: string | undefined;
|
|
878
975
|
template?: string | undefined;
|
|
976
|
+
notificationId: number;
|
|
879
977
|
to: string | string[];
|
|
978
|
+
}, void>;
|
|
979
|
+
sendBulkEmailItem: _spfn_core_job.JobDef<{
|
|
980
|
+
html?: string | undefined;
|
|
981
|
+
text?: string | undefined;
|
|
982
|
+
replyTo?: string | undefined;
|
|
983
|
+
subject: string;
|
|
984
|
+
notificationId: number;
|
|
985
|
+
to: string[];
|
|
986
|
+
from: string;
|
|
987
|
+
}, void>;
|
|
988
|
+
sendBulkSmsItem: _spfn_core_job.JobDef<{
|
|
989
|
+
notificationId: number;
|
|
990
|
+
to: string;
|
|
991
|
+
message: string;
|
|
992
|
+
}, void>;
|
|
993
|
+
sendBulkSlackItem: _spfn_core_job.JobDef<{
|
|
994
|
+
text?: string | undefined;
|
|
995
|
+
blocks?: unknown[] | undefined;
|
|
880
996
|
notificationId: number;
|
|
997
|
+
webhookUrl: string;
|
|
881
998
|
}, void>;
|
|
882
999
|
}>;
|
|
883
1000
|
|
|
@@ -1052,4 +1169,4 @@ interface ClickDetail {
|
|
|
1052
1169
|
*/
|
|
1053
1170
|
declare function getClickDetails(notificationId: number): Promise<ClickDetail[]>;
|
|
1054
1171
|
|
|
1055
|
-
export { type CancelResult, type ClickDetail, EmailProvider, type EngagementStats, type ErrorSlackOptions, type FindNotificationsOptions, NOTIFICATION_CHANNELS, NOTIFICATION_STATUSES, type NewNotification, type Notification, NotificationChannel$1 as NotificationChannel, type NotificationStats, type NotificationStatus, SMSProvider, type ScheduleOptions, type ScheduleResult, SendEmailParams, SendResult, SendSMSParams, SendSlackParams, SlackProvider, TRACKING_EVENT_TYPES, TemplateData, TemplateDefinition, type TrackingEvent, type TrackingEventType, type TrackingStats, cancelNotification, cancelNotificationsByReference, cancelScheduledNotification, countNotifications, createErrorSlackNotifier, createNotificationRecord, createScheduledNotification, findNotificationByJobId, findNotifications, findScheduledNotifications, getClickDetails, getEngagementStats, getNotificationStats, getTemplate, getTemplateNames, getTrackingStats, hasTemplate, markNotificationFailed, markNotificationPending, markNotificationSent, notificationJobRouter, notifications, processTrackingHtml, registerBuiltinTemplates, registerEmailProvider, registerFilter, registerSMSProvider, registerSlackProvider, registerTemplate, renderTemplate, scheduleEmail, scheduleSMS, sendEmail, sendEmailBulk, sendSMS, sendSMSBulk, sendScheduledEmailJob, sendScheduledSmsJob, sendSlack, sendSlackBulk, trackingEvents, trackingRouter, updateNotificationJobId };
|
|
1172
|
+
export { type BulkEmailOptions, type BulkEmailResult, type BulkSMSOptions, type BulkSMSResult, type BulkSlackOptions, type BulkSlackResult, type CancelResult, type ClickDetail, EmailProvider, type EngagementStats, type ErrorSlackOptions, type FindNotificationsOptions, NOTIFICATION_CHANNELS, NOTIFICATION_STATUSES, type NewNotification, type Notification, NotificationChannel$1 as NotificationChannel, type NotificationStats, type NotificationStatus, SMSProvider, type ScheduleOptions, type ScheduleResult, SendEmailParams, SendResult, SendSMSParams, SendSlackParams, SlackProvider, TRACKING_EVENT_TYPES, TemplateData, TemplateDefinition, type TrackingEvent, type TrackingEventType, type TrackingStats, cancelNotification, cancelNotificationsByReference, cancelScheduledNotification, countNotifications, createErrorSlackNotifier, createNotificationRecord, createScheduledNotification, findNotificationByJobId, findNotifications, findScheduledNotifications, getClickDetails, getEngagementStats, getNotificationStats, getTemplate, getTemplateNames, getTrackingStats, hasTemplate, markNotificationFailed, markNotificationPending, markNotificationSent, notificationJobRouter, notifications, processTrackingHtml, registerBuiltinTemplates, registerEmailProvider, registerFilter, registerSMSProvider, registerSlackProvider, registerTemplate, renderTemplate, scheduleEmail, scheduleSMS, sendBulkEmailItemJob, sendBulkSlackItemJob, sendBulkSmsItemJob, sendEmail, sendEmailBulk, sendSMS, sendSMSBulk, sendScheduledEmailJob, sendScheduledSmsJob, sendSlack, sendSlackBulk, trackingEvents, trackingRouter, updateNotificationJobId };
|