@stone-js/notifications 0.8.17
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/LICENSE +21 -0
- package/README.md +318 -0
- package/dist/NoticeRegistry.d.ts +44 -0
- package/dist/NotificationManager.d.ts +49 -0
- package/dist/NotificationServiceProvider.d.ts +40 -0
- package/dist/Notifier.d.ts +260 -0
- package/dist/channels/InAppChannel.d.ts +43 -0
- package/dist/channels/LogChannel.d.ts +43 -0
- package/dist/channels/SmtpChannel.d.ts +46 -0
- package/dist/constants.d.ts +6 -0
- package/dist/declarations.d.ts +345 -0
- package/dist/decorators/Notice.d.ts +50 -0
- package/dist/decorators/NotificationChannel.d.ts +34 -0
- package/dist/decorators/Notifications.d.ts +26 -0
- package/dist/decorators/constants.d.ts +14 -0
- package/dist/defineNotice.d.ts +24 -0
- package/dist/errors/NotificationError.d.ts +12 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +1481 -0
- package/dist/jobs/DeliverNotification.d.ts +30 -0
- package/dist/middleware/NoticeSubscriptionsMiddleware.d.ts +25 -0
- package/dist/options/NotificationsBlueprint.d.ts +37 -0
- package/dist/render.d.ts +36 -0
- package/package.json +114 -0
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import { IBlueprint, IContainer } from '@stone-js/core';
|
|
2
|
+
import { DeliveryOutcome, NotificationReceipt, NotifyOptions, Recipient, RecipientInput, RenderedNotification } from './declarations.js';
|
|
3
|
+
/** The shape this module needs from a queue, duck-typed so `@stone-js/queue` is never imported. */
|
|
4
|
+
export interface QueueLike {
|
|
5
|
+
dispatch: <T>(name: string, payload: T, options?: Record<string, unknown>) => Promise<string>;
|
|
6
|
+
later?: <T>(delay: number, name: string, payload: T, options?: Record<string, unknown>) => Promise<string>;
|
|
7
|
+
}
|
|
8
|
+
/** The shape this module needs from a cache store, for deduplication only. */
|
|
9
|
+
export interface CacheLike {
|
|
10
|
+
add: <T>(key: string, value: T, options?: Record<string, unknown>) => Promise<boolean>;
|
|
11
|
+
}
|
|
12
|
+
/** The shape this module needs from a cache manager, to reach a named store. */
|
|
13
|
+
export interface CacheManagerLike {
|
|
14
|
+
store: (name?: string) => CacheLike;
|
|
15
|
+
}
|
|
16
|
+
/** The shape this module needs from an event bus, to announce what it delivered. */
|
|
17
|
+
export interface EventBusLike {
|
|
18
|
+
emit: <T>(name: string, payload?: T, options?: Record<string, unknown>) => Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
/** What a queued delivery carries. Resolved and rendered already: a worker guesses nothing. */
|
|
21
|
+
export interface DeliveryPayload {
|
|
22
|
+
recipient: Recipient;
|
|
23
|
+
template: string;
|
|
24
|
+
params: Record<string, unknown>;
|
|
25
|
+
locale: string;
|
|
26
|
+
channels: string[];
|
|
27
|
+
/** The notice that produced it, when one did, so the worker asks the same class for the content. */
|
|
28
|
+
notice?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* What an application calls to reach someone.
|
|
32
|
+
*
|
|
33
|
+
* The one sentence that shapes everything here: **decide now, deliver later.** A request resolves who
|
|
34
|
+
* the person is, renders the message in their language, and hands the delivery to a queue. Reaching a
|
|
35
|
+
* mail provider takes as long as it takes, and a request that waits for one is a request that times
|
|
36
|
+
* out on a function-as-a-service platform, from the endpoint the user is watching.
|
|
37
|
+
*
|
|
38
|
+
* It also never throws at its caller. A notification is almost always a side effect of something that
|
|
39
|
+
* already succeeded: an account was created, a guardian was invited. Failing that operation because a
|
|
40
|
+
* mail provider was down would undo work that was correct. Every failure comes back as an outcome and
|
|
41
|
+
* goes to the log.
|
|
42
|
+
*/
|
|
43
|
+
export declare class Notifier {
|
|
44
|
+
private readonly blueprint;
|
|
45
|
+
private readonly container?;
|
|
46
|
+
/**
|
|
47
|
+
* @param dependencies - Auto-wired services.
|
|
48
|
+
*/
|
|
49
|
+
constructor({ blueprint, container }: {
|
|
50
|
+
blueprint: IBlueprint;
|
|
51
|
+
container?: IContainer;
|
|
52
|
+
});
|
|
53
|
+
/**
|
|
54
|
+
* Tell someone something.
|
|
55
|
+
*
|
|
56
|
+
* @param to - Who to tell: a recipient, an id, or several of either.
|
|
57
|
+
* @param template - The template key. Never a rendered body: what is not copied does not have to
|
|
58
|
+
* be erased, and a key survives a translation being fixed.
|
|
59
|
+
* @param params - What the template needs.
|
|
60
|
+
* @param options - Which channels, which language, whether to wait.
|
|
61
|
+
* @returns What happened, or that it was queued.
|
|
62
|
+
*/
|
|
63
|
+
notify(to: RecipientInput | RecipientInput[], template: string, params?: Record<string, unknown>, options?: NotifyOptions): Promise<NotificationReceipt>;
|
|
64
|
+
/**
|
|
65
|
+
* Deliver what a notice says about a domain event.
|
|
66
|
+
*
|
|
67
|
+
* The entry the event subscription calls, and the reason this module is not a service somebody has
|
|
68
|
+
* to remember to call: a module emits what happened, and the notice that named that event decides
|
|
69
|
+
* who learns about it. The emitting module knows nothing about any of this.
|
|
70
|
+
*
|
|
71
|
+
* @param name - The notice's name.
|
|
72
|
+
* @param event - The domain event, as the bus delivered it.
|
|
73
|
+
* @returns What happened, or that it was queued.
|
|
74
|
+
*/
|
|
75
|
+
deliverNotice(name: string, event: unknown): Promise<NotificationReceipt>;
|
|
76
|
+
/**
|
|
77
|
+
* What a notice would send, without sending it.
|
|
78
|
+
*
|
|
79
|
+
* For a screen that shows a member of staff what a guardian is about to receive, and for a test
|
|
80
|
+
* that checks a notice without a channel. It renders exactly what delivery would render, per
|
|
81
|
+
* channel, which is what makes it worth having rather than approximating.
|
|
82
|
+
*
|
|
83
|
+
* @param to - Who it would be for.
|
|
84
|
+
* @param template - The notice or template name.
|
|
85
|
+
* @param params - What it needs.
|
|
86
|
+
* @param options - Which channels, which language.
|
|
87
|
+
* @returns One rendered message per recipient and channel.
|
|
88
|
+
*/
|
|
89
|
+
preview(to: RecipientInput | RecipientInput[], template: string, params?: Record<string, unknown>, options?: NotifyOptions): Promise<Array<{
|
|
90
|
+
recipient: Recipient;
|
|
91
|
+
channel: string;
|
|
92
|
+
message: RenderedNotification;
|
|
93
|
+
}>>;
|
|
94
|
+
/**
|
|
95
|
+
* Perform one delivery, to one person, on every channel it names.
|
|
96
|
+
*
|
|
97
|
+
* Called here when nothing is queued, and by the queue job when something is. Same code either way,
|
|
98
|
+
* which is what makes a retry mean exactly what the first attempt meant.
|
|
99
|
+
*
|
|
100
|
+
* @param payload - Who, what, where, in which language.
|
|
101
|
+
* @returns What each channel answered.
|
|
102
|
+
*/
|
|
103
|
+
deliver(payload: DeliveryPayload): Promise<DeliveryOutcome[]>;
|
|
104
|
+
/**
|
|
105
|
+
* What the notice says, for this person, or nothing when there is no notice.
|
|
106
|
+
*
|
|
107
|
+
* Failing here must not fail the delivery: a notice is application code, and application code
|
|
108
|
+
* throws. The message then falls back to the template path, which at worst renders the key, and
|
|
109
|
+
* the failure is named rather than swallowed.
|
|
110
|
+
*
|
|
111
|
+
* @param declaration - The notice, when one is declared.
|
|
112
|
+
* @param params - The event or params it is given.
|
|
113
|
+
* @param context - Who it is for, and in which language.
|
|
114
|
+
* @returns The content, or nothing.
|
|
115
|
+
*/
|
|
116
|
+
private contentFrom;
|
|
117
|
+
/**
|
|
118
|
+
* The message one channel receives.
|
|
119
|
+
*
|
|
120
|
+
* A notice's content wins, per channel, because that is the whole reason it returns a map: a text
|
|
121
|
+
* message is not an email, one having a subject and room to explain and the other a hundred and
|
|
122
|
+
* sixty characters. Failing that, the template path renders it.
|
|
123
|
+
*
|
|
124
|
+
* @param channel - The channel about to send.
|
|
125
|
+
* @param template - The notice or template name.
|
|
126
|
+
* @param params - What it was given.
|
|
127
|
+
* @param locale - The recipient's language.
|
|
128
|
+
* @param content - What the notice said, if anything.
|
|
129
|
+
* @returns The rendered message.
|
|
130
|
+
*/
|
|
131
|
+
private messageFor;
|
|
132
|
+
/**
|
|
133
|
+
* The content for one channel, out of what a notice returned.
|
|
134
|
+
*
|
|
135
|
+
* Three shapes, all useful: a map keyed by channel, one content for every channel, or a bare
|
|
136
|
+
* string. A map that names no content for this channel falls through to the template path rather
|
|
137
|
+
* than sending an empty body.
|
|
138
|
+
*
|
|
139
|
+
* @param channel - The channel about to send.
|
|
140
|
+
* @param content - What the notice said.
|
|
141
|
+
* @returns The content, or nothing.
|
|
142
|
+
*/
|
|
143
|
+
private contentFor;
|
|
144
|
+
/**
|
|
145
|
+
* One channel, one message, and an answer whatever happens.
|
|
146
|
+
*
|
|
147
|
+
* A channel that throws is treated as **retryable**, because a throw is an adapter bug rather than
|
|
148
|
+
* a verdict, and burying a channel's whole traffic the day a provider client changes its error
|
|
149
|
+
* shapes would be worse than one retry too many.
|
|
150
|
+
*
|
|
151
|
+
* @param manager - The channel registry.
|
|
152
|
+
* @param name - The channel to use.
|
|
153
|
+
* @param message - The rendered notification.
|
|
154
|
+
* @param recipient - Who it is for.
|
|
155
|
+
* @returns The outcome, always.
|
|
156
|
+
*/
|
|
157
|
+
private sendOn;
|
|
158
|
+
/**
|
|
159
|
+
* Hand one delivery to the queue.
|
|
160
|
+
*
|
|
161
|
+
* Rendered arguments are **not** carried: the payload holds the key and the params, so a message
|
|
162
|
+
* queued before a translation was fixed goes out fixed, and a queue dump holds no message bodies.
|
|
163
|
+
*
|
|
164
|
+
* @param queue - The queue.
|
|
165
|
+
* @param recipient - Who it is for.
|
|
166
|
+
* @param template - The template key.
|
|
167
|
+
* @param params - What it needs.
|
|
168
|
+
* @param channels - Where to send it.
|
|
169
|
+
* @param options - What the caller asked for.
|
|
170
|
+
*/
|
|
171
|
+
private enqueue;
|
|
172
|
+
/**
|
|
173
|
+
* Everyone this notification is for, as people rather than ids.
|
|
174
|
+
*
|
|
175
|
+
* An id is resolved through the application's own directory, so the address is read at send time.
|
|
176
|
+
* One that resolves to nobody is dropped with a warning: sending to an id nobody recognises is not
|
|
177
|
+
* something to guess at.
|
|
178
|
+
*
|
|
179
|
+
* @param inputs - The recipients, or their ids.
|
|
180
|
+
* @returns The recipients that could be resolved.
|
|
181
|
+
*/
|
|
182
|
+
private resolveAll;
|
|
183
|
+
/**
|
|
184
|
+
* The language to write in.
|
|
185
|
+
*
|
|
186
|
+
* The recipient's own, first and almost always. An explicit override exists because a few messages
|
|
187
|
+
* are genuinely about the sender's context, and it is rarely the right answer.
|
|
188
|
+
*
|
|
189
|
+
* @param recipient - Who it is for.
|
|
190
|
+
* @param options - What the caller asked for.
|
|
191
|
+
* @returns The locale.
|
|
192
|
+
*/
|
|
193
|
+
private localeFor;
|
|
194
|
+
/**
|
|
195
|
+
* The queue to dispatch on, or nothing when this delivery happens here.
|
|
196
|
+
*
|
|
197
|
+
* @param options - What the caller asked for.
|
|
198
|
+
* @returns The queue, or nothing.
|
|
199
|
+
*/
|
|
200
|
+
private queue;
|
|
201
|
+
/**
|
|
202
|
+
* Say once that nothing is being delivered.
|
|
203
|
+
*
|
|
204
|
+
* The zero-config default writes to the log and reaches nobody. That is the right default, and a
|
|
205
|
+
* module that delivered nothing while looking like one that delivers is the failure this warning
|
|
206
|
+
* exists to prevent.
|
|
207
|
+
*
|
|
208
|
+
* @param channels - The channels in use.
|
|
209
|
+
*/
|
|
210
|
+
private warnOnceAboutTheDefault;
|
|
211
|
+
/** Whether the default has already been reported, for this notifier. */
|
|
212
|
+
private warned;
|
|
213
|
+
/**
|
|
214
|
+
* Whether this exact occurrence has already gone out.
|
|
215
|
+
*
|
|
216
|
+
* The answer to the most common production failure of any notification system: the same message
|
|
217
|
+
* twice, because a queue is at-least-once, because a retry half succeeded, or because two events
|
|
218
|
+
* describe one fact. Keys live in `@stone-js/cache`, so the store is the one the application
|
|
219
|
+
* already chose and this module stores nothing of its own.
|
|
220
|
+
*
|
|
221
|
+
* `add` is the atomic set-if-absent every store implements, which is what makes this a claim rather
|
|
222
|
+
* than a read followed by a hopeful write.
|
|
223
|
+
*
|
|
224
|
+
* @param template - The notice or template name, so two notices cannot collide on one key.
|
|
225
|
+
* @param key - What makes this occurrence unique, when anything does.
|
|
226
|
+
* @returns True when it was already sent.
|
|
227
|
+
*/
|
|
228
|
+
private alreadySent;
|
|
229
|
+
/**
|
|
230
|
+
* Announce one delivery on the event bus.
|
|
231
|
+
*
|
|
232
|
+
* How an application keeps a delivery ledger without this module owning one. "Why did they never
|
|
233
|
+
* receive it" is the question a notification system exists to answer, and the answer belongs in
|
|
234
|
+
* whatever the application already queries: it listens, and writes what it needs.
|
|
235
|
+
*
|
|
236
|
+
* @param outcome - What the channel answered.
|
|
237
|
+
* @param payload - What was being delivered.
|
|
238
|
+
*/
|
|
239
|
+
private announce;
|
|
240
|
+
/** Say something once per notifier, so a standing condition is stated rather than repeated. */
|
|
241
|
+
private warnOnce;
|
|
242
|
+
/** What has already been said. */
|
|
243
|
+
private readonly said;
|
|
244
|
+
/** The notice registry, built for this event like everything else. */
|
|
245
|
+
private notices;
|
|
246
|
+
/** The registry, once. */
|
|
247
|
+
private registry?;
|
|
248
|
+
/** The cache store deduplication is remembered in, when one is bound. */
|
|
249
|
+
private cache;
|
|
250
|
+
/** The event bus, when one is bound. */
|
|
251
|
+
private bus;
|
|
252
|
+
/** The `stone.notifications` bucket. */
|
|
253
|
+
private options;
|
|
254
|
+
/** The channel registry, from the container when there is one. */
|
|
255
|
+
private manager;
|
|
256
|
+
/** The translation catalogue, when one is bound. */
|
|
257
|
+
private translator;
|
|
258
|
+
/** The logger, when one is bound. */
|
|
259
|
+
private logger;
|
|
260
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { DeliveryOutcome, InAppChannelConfig, NotificationChannel, Recipient, RenderedNotification } from '../declarations.js';
|
|
2
|
+
/** The shape this channel needs from a broadcaster, duck-typed so no realtime import is required. */
|
|
3
|
+
export interface BroadcasterLike {
|
|
4
|
+
to: (channel: string) => {
|
|
5
|
+
emit: <T>(event: string, payload?: T) => Promise<void>;
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* The channel that reaches the tab someone already has open.
|
|
10
|
+
*
|
|
11
|
+
* This is the half that makes a notification module worth having in this framework rather than a mail
|
|
12
|
+
* client wrapped in a service: **one `notify()` reaches the mailbox, the phone and the open screen**,
|
|
13
|
+
* and the application wires none of the three together.
|
|
14
|
+
*
|
|
15
|
+
* It broadcasts through `@stone-js/realtime`, duck-typed from the container, so this package neither
|
|
16
|
+
* imports it nor requires it. The client side is already written: whoever is subscribed to the
|
|
17
|
+
* recipient's channel receives a `notification` event, with the same rendered message every other
|
|
18
|
+
* channel got.
|
|
19
|
+
*
|
|
20
|
+
* It reports `unreachable` rather than `failed` when nobody is listening, because that is not an
|
|
21
|
+
* error: a person who is not looking at the screen is exactly why the other channels exist.
|
|
22
|
+
*/
|
|
23
|
+
export declare class InAppChannel implements NotificationChannel {
|
|
24
|
+
readonly name: string;
|
|
25
|
+
private readonly event;
|
|
26
|
+
private readonly broadcaster?;
|
|
27
|
+
private readonly channelFor;
|
|
28
|
+
/**
|
|
29
|
+
* @param config - Names the channel, and how to address a recipient.
|
|
30
|
+
* @param broadcaster - The realtime broadcaster, when one is bound.
|
|
31
|
+
* @returns A channel.
|
|
32
|
+
*/
|
|
33
|
+
static create(config?: InAppChannelConfig, broadcaster?: BroadcasterLike): InAppChannel;
|
|
34
|
+
constructor(config?: InAppChannelConfig, broadcaster?: BroadcasterLike);
|
|
35
|
+
/**
|
|
36
|
+
* Broadcast the message on the recipient's own channel.
|
|
37
|
+
*
|
|
38
|
+
* @param message - The rendered notification.
|
|
39
|
+
* @param recipient - Who it is for.
|
|
40
|
+
* @returns How it ended.
|
|
41
|
+
*/
|
|
42
|
+
send(message: RenderedNotification, recipient: Recipient): Promise<DeliveryOutcome>;
|
|
43
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { ILogger } from '@stone-js/core';
|
|
2
|
+
import { ChannelConfig, DeliveryOutcome, NotificationChannel, Recipient, RenderedNotification } from '../declarations.js';
|
|
3
|
+
/**
|
|
4
|
+
* The channel that delivers nothing, and is honest about it.
|
|
5
|
+
*
|
|
6
|
+
* The zero-config default, so an application can call `notify()` on its first day and watch what it
|
|
7
|
+
* would have sent. It is the right choice in development and in a test, and **it is not a channel**
|
|
8
|
+
* anywhere else: nobody receives anything.
|
|
9
|
+
*
|
|
10
|
+
* It exists rather than defaulting to a real one because a default that quietly sent real mail would
|
|
11
|
+
* send it from the first test run, to real people. The notifier says once, in a warning, that this is
|
|
12
|
+
* what is configured, for the same reason: a module that delivers nothing must not look like one that
|
|
13
|
+
* delivers.
|
|
14
|
+
*/
|
|
15
|
+
export declare class LogChannel implements NotificationChannel {
|
|
16
|
+
readonly name: string;
|
|
17
|
+
private readonly logger?;
|
|
18
|
+
/**
|
|
19
|
+
* @param config - Names the channel.
|
|
20
|
+
* @param logger - Where the message goes, when one is bound.
|
|
21
|
+
* @returns A channel.
|
|
22
|
+
*/
|
|
23
|
+
static create(config?: ChannelConfig, logger?: ILogger): LogChannel;
|
|
24
|
+
constructor(name?: string, logger?: ILogger);
|
|
25
|
+
/**
|
|
26
|
+
* Write the message where the application writes everything else.
|
|
27
|
+
*
|
|
28
|
+
* @param message - The rendered notification.
|
|
29
|
+
* @param recipient - Who it was for.
|
|
30
|
+
* @returns Sent, because writing it down is all this channel promises.
|
|
31
|
+
*/
|
|
32
|
+
send(message: RenderedNotification, recipient: Recipient): Promise<DeliveryOutcome>;
|
|
33
|
+
/**
|
|
34
|
+
* Who it was for, named without spelling out an address.
|
|
35
|
+
*
|
|
36
|
+
* A log line is read by more people than a database row, so it carries enough to follow a message
|
|
37
|
+
* and not enough to leak one.
|
|
38
|
+
*
|
|
39
|
+
* @param recipient - Who it was for.
|
|
40
|
+
* @returns Something to call them in a log.
|
|
41
|
+
*/
|
|
42
|
+
private addresseeOf;
|
|
43
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { DeliveryOutcome, NotificationChannel, Recipient, RenderedNotification, SmtpChannelConfig } from '../declarations.js';
|
|
2
|
+
/**
|
|
3
|
+
* Email, over SMTP.
|
|
4
|
+
*
|
|
5
|
+
* SMTP rather than a provider's API, deliberately: every provider speaks it, so shipping this one
|
|
6
|
+
* channel reaches all of them without this package choosing a vendor for you. A provider with an API
|
|
7
|
+
* you prefer is a `factory` away.
|
|
8
|
+
*
|
|
9
|
+
* `nodemailer` is an optional peer, imported lazily, so an application that sends no mail carries no
|
|
10
|
+
* mail dependency. The transport is built once per channel instance and the instance is rebuilt with
|
|
11
|
+
* the container: a transport is a **resource**, not state, and nodemailer pools its own connections,
|
|
12
|
+
* so an application under load should pass a transport it owns.
|
|
13
|
+
*/
|
|
14
|
+
export declare class SmtpChannel implements NotificationChannel {
|
|
15
|
+
readonly name: string;
|
|
16
|
+
private readonly config;
|
|
17
|
+
private transportPromise?;
|
|
18
|
+
/**
|
|
19
|
+
* @param config - The channel's configuration.
|
|
20
|
+
* @returns A channel.
|
|
21
|
+
*/
|
|
22
|
+
static create(config: SmtpChannelConfig): SmtpChannel;
|
|
23
|
+
constructor(config: SmtpChannelConfig);
|
|
24
|
+
/**
|
|
25
|
+
* Send the message as mail.
|
|
26
|
+
*
|
|
27
|
+
* @param message - The rendered notification.
|
|
28
|
+
* @param recipient - Who it is for.
|
|
29
|
+
* @returns How it ended.
|
|
30
|
+
*/
|
|
31
|
+
send(message: RenderedNotification, recipient: Recipient): Promise<DeliveryOutcome>;
|
|
32
|
+
/** The transport, built once for this instance. */
|
|
33
|
+
private transport;
|
|
34
|
+
/** Build the transport from what was configured, or say what is missing. */
|
|
35
|
+
private build;
|
|
36
|
+
/**
|
|
37
|
+
* Load `nodemailer`, an optional peer, and say plainly when it is not there.
|
|
38
|
+
*
|
|
39
|
+
* A missing package is a setup mistake, never a delivery failure: answering "could not send" would
|
|
40
|
+
* put it in the retry queue forever, and the retry would fail identically every time.
|
|
41
|
+
*
|
|
42
|
+
* @returns The nodemailer module.
|
|
43
|
+
* @throws {NotificationConfigurationError} When the package is absent.
|
|
44
|
+
*/
|
|
45
|
+
private loadNodemailer;
|
|
46
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** The queue job that performs a delivery. */
|
|
2
|
+
export declare const DELIVERY_JOB: string;
|
|
3
|
+
/** The channel used when nothing is configured. It delivers nothing, and says so. */
|
|
4
|
+
export declare const DEFAULT_CHANNEL: string;
|
|
5
|
+
/** The event an in-app client listens for. */
|
|
6
|
+
export declare const IN_APP_EVENT: string;
|