@mpgd/game-services 0.33.1 → 0.35.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.
@@ -1,4 +1,6 @@
1
1
  import { NotificationError, type NotificationConsentRecord, type NotificationDeliveryOutcome, type NotificationDeployment, type NotificationNotice, type NotificationTemplateData } from '@mpgd/platform/notifications';
2
+ import { type NotificationBulkDeliverOptions, type NotificationBulkDeliveryResult } from './bulk.js';
3
+ import { type NotificationCopyResolver } from './copy.js';
2
4
  import { type NotificationProviderRegistry, type NotificationProviderRegistrySnapshot, type NotificationServiceCatalog } from './registry.js';
3
5
  import { type NotificationNoticeChannel, type NotificationPurgeCounts, type NotificationStore } from './store.js';
4
6
  /**
@@ -70,6 +72,17 @@ export interface CreateNotificationServiceInput {
70
72
  readonly player: string;
71
73
  }) => string | undefined | Promise<string | undefined>;
72
74
  /**
75
+ * Chooses a send's title and body per recipient locale where the content
76
+ * comes from copy (not a mapping's own text or a host template): reminders,
77
+ * consent notices, and direct sends alike. It replaces the default,
78
+ * `resolveCatalogNotificationCopy` (the catalog's `copy`, falling back to
79
+ * the language and then `defaultLocale`); a resolver that wants that
80
+ * fallback calls it. No copy skips the recipient as `unavailable:
81
+ * copy-missing`, and a resolver that throws is retried as a host that
82
+ * cannot answer is.
83
+ */
84
+ readonly resolveCopy?: NotificationCopyResolver;
85
+ /**
73
86
  * Runs dispatch jobs later, so a fan-out never exceeds one invocation's
74
87
  * subrequest limit. Without it every job runs inline before `deliver`
75
88
  * answers.
@@ -159,6 +172,25 @@ export interface NotificationService {
159
172
  }): Promise<void>;
160
173
  /** One send through the ledger, the gate, and the providers. */
161
174
  deliver(input: unknown): Promise<NotificationDeliveryOutcome>;
175
+ /**
176
+ * A bulk send (RFC open question 5): one topic to many players through one
177
+ * provider, each recipient a single send with its own key
178
+ * (`<idempotencyKey>:<encodeURIComponent(player)>`), ledger row, and gate
179
+ * check, made immediately before its batch's provider call. Recipients the
180
+ * gate refuses never reach the provider. A provider with a bulk capability
181
+ * gets one `sendBatch` call per batch of allowed recipients (one `send`
182
+ * each below its `minRecipients` or inside its hold window); any other
183
+ * provider gets one `send` per recipient. The same call retried answers
184
+ * recipients already sent from the ledger and sends only the rest.
185
+ *
186
+ * It is an operator action from the game's server, like `deliver`: never
187
+ * serve it to a client session. `options` are the host's bounds: no batch
188
+ * starts after `budgetMs`, and recipients past `maxRecipients` attempts, or
189
+ * past the provider's `rate` budget, answer `not-attempted`. A recipient
190
+ * answered from the ledger is no attempt, though its key is still read:
191
+ * resend only the `not-attempted` recipients to keep a retry small.
192
+ */
193
+ deliverBulk(input: unknown, options?: NotificationBulkDeliverOptions): Promise<NotificationBulkDeliveryResult>;
162
194
  /** Runs one queued dispatch job; a job that is no longer due does nothing. */
163
195
  dispatch(job: NotificationDispatchJob): Promise<void>;
164
196
  /**