@mrrocket/sdk 0.4.0 → 0.9.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.
- package/CHANGELOG.md +43 -0
- package/README.md +137 -8
- package/dist/api-client.d.ts +213 -0
- package/dist/api-client.js +67 -0
- package/dist/api-client.js.map +1 -0
- package/dist/api.d.ts +9 -109
- package/dist/api.js +7 -62
- package/dist/api.js.map +1 -1
- package/dist/browser/mrrocket-flows.js +64 -0
- package/dist/browser/mrrocket-messenger.js +313 -0
- package/dist/browser/mrrocket-push.js +1 -0
- package/dist/browser/mrrocket-replay.js +3 -3
- package/dist/browser/mrrocket-sw.js +1 -0
- package/dist/browser/mrrocket.js +2 -1
- package/dist/browser.d.ts +3 -2
- package/dist/browser.js +6 -1
- package/dist/browser.js.map +1 -1
- package/dist/capture.d.ts +1 -13
- package/dist/capture.js +1 -22
- package/dist/capture.js.map +1 -1
- package/dist/client.d.ts +36 -1
- package/dist/client.js +161 -6
- package/dist/client.js.map +1 -1
- package/dist/context.d.ts +10 -0
- package/dist/context.js.map +1 -1
- package/dist/core.d.ts +64 -3
- package/dist/core.js +54 -2
- package/dist/core.js.map +1 -1
- package/dist/feedback.d.ts +19 -4
- package/dist/feedback.js +655 -190
- package/dist/feedback.js.map +1 -1
- package/dist/flows-ui.d.ts +23 -0
- package/dist/flows-ui.js +384 -0
- package/dist/flows-ui.js.map +1 -0
- package/dist/flows-web.d.ts +19 -0
- package/dist/flows-web.js +42 -0
- package/dist/flows-web.js.map +1 -0
- package/dist/flows.d.ts +222 -0
- package/dist/flows.js +409 -0
- package/dist/flows.js.map +1 -0
- package/dist/index.d.ts +5 -2
- package/dist/index.js +13 -1
- package/dist/index.js.map +1 -1
- package/dist/messenger-ui.d.ts +47 -0
- package/dist/messenger-ui.js +583 -0
- package/dist/messenger-ui.js.map +1 -0
- package/dist/messenger.d.ts +37 -0
- package/dist/messenger.js +69 -0
- package/dist/messenger.js.map +1 -0
- package/dist/proxy.d.ts +34 -1
- package/dist/proxy.js +14 -1
- package/dist/proxy.js.map +1 -1
- package/dist/push-web.d.ts +43 -0
- package/dist/push-web.js +81 -0
- package/dist/push-web.js.map +1 -0
- package/dist/rage.d.ts +14 -0
- package/dist/rage.js +27 -0
- package/dist/rage.js.map +1 -0
- package/dist/react-native/index.d.cts +640 -3
- package/dist/react-native/index.d.ts +640 -3
- package/dist/react-native/index.js +2015 -34
- package/dist/react-native/index.js.map +1 -1
- package/dist/styles-css.d.ts +6 -0
- package/dist/styles-css.js +327 -0
- package/dist/styles-css.js.map +1 -0
- package/dist/styles.d.ts +1 -2
- package/dist/styles.js +3 -134
- package/dist/styles.js.map +1 -1
- package/dist/ui.d.ts +3 -0
- package/dist/ui.js +12 -0
- package/dist/ui.js.map +1 -1
- package/package.json +20 -4
|
@@ -1,19 +1,408 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* The SDK's fetch client and the shapes it reads, without React, so the script tag's widgets (src/script) use it too.
|
|
6
|
+
* `./api` re-exports all of it with the `useApi` hook.
|
|
7
|
+
*/
|
|
8
|
+
type PostStatus = "review" | "planned" | "progress" | "shipped";
|
|
9
|
+
interface FeedbackBoardInfo {
|
|
10
|
+
id: string;
|
|
11
|
+
label: string;
|
|
12
|
+
}
|
|
13
|
+
interface FeedbackPost {
|
|
14
|
+
id: string;
|
|
15
|
+
title: string;
|
|
16
|
+
body: string;
|
|
17
|
+
board: string;
|
|
18
|
+
status: PostStatus;
|
|
19
|
+
votes: number;
|
|
20
|
+
comments: number;
|
|
21
|
+
voted: boolean;
|
|
22
|
+
createdAt: string;
|
|
23
|
+
/** "Lena K.", "Anonymous" or "Team". Missing from servers before SDK 0.6. */
|
|
24
|
+
author?: string;
|
|
25
|
+
}
|
|
26
|
+
/** The product's public face for the board's header. */
|
|
27
|
+
interface FeedbackProduct {
|
|
28
|
+
name: string;
|
|
29
|
+
logo: string | null;
|
|
30
|
+
/** The domain's favicon, tried when `logo` does not load. Older servers leave it out. */
|
|
31
|
+
logoFallback?: string | null;
|
|
32
|
+
}
|
|
33
|
+
interface FeedbackList {
|
|
34
|
+
boards: FeedbackBoardInfo[];
|
|
35
|
+
posts: FeedbackPost[];
|
|
36
|
+
product?: FeedbackProduct;
|
|
37
|
+
}
|
|
38
|
+
interface FeedbackRoadmap {
|
|
39
|
+
/** `review` (Backlog) comes from servers of SDK 0.6 on. */
|
|
40
|
+
columns: {
|
|
41
|
+
review?: FeedbackPost[];
|
|
42
|
+
planned: FeedbackPost[];
|
|
43
|
+
progress: FeedbackPost[];
|
|
44
|
+
shipped: FeedbackPost[];
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
interface ChangelogEntry {
|
|
48
|
+
id: string;
|
|
49
|
+
title: string;
|
|
50
|
+
body: string;
|
|
51
|
+
publishedAt: string;
|
|
52
|
+
}
|
|
53
|
+
interface FeedbackComment {
|
|
54
|
+
id: string;
|
|
55
|
+
body: string;
|
|
56
|
+
author: string;
|
|
57
|
+
isTeam: boolean;
|
|
58
|
+
postedAt: string;
|
|
59
|
+
}
|
|
60
|
+
type SurveyQuestionKind = "nps" | "rating" | "single" | "multi" | "text";
|
|
61
|
+
interface SurveyQuestion {
|
|
62
|
+
key: string;
|
|
63
|
+
kind: SurveyQuestionKind;
|
|
64
|
+
title: string;
|
|
65
|
+
description?: string;
|
|
66
|
+
required: boolean;
|
|
67
|
+
options?: string[];
|
|
68
|
+
scale?: number;
|
|
69
|
+
low?: string;
|
|
70
|
+
high?: string;
|
|
71
|
+
placeholder?: string;
|
|
72
|
+
}
|
|
73
|
+
interface SurveyDefinition {
|
|
74
|
+
id: string;
|
|
75
|
+
name: string;
|
|
76
|
+
type: string;
|
|
77
|
+
thanks: string;
|
|
78
|
+
questions: SurveyQuestion[];
|
|
79
|
+
}
|
|
80
|
+
type SurveyAnswer = number | string | string[];
|
|
81
|
+
/** One message of the messenger's chat. "visitor" is the person on the site; the rest come from the product's team. */
|
|
82
|
+
interface ChatMessage {
|
|
83
|
+
id: string;
|
|
84
|
+
from: "visitor" | "team" | "ai" | "auto";
|
|
85
|
+
body: string;
|
|
86
|
+
at: string;
|
|
87
|
+
/** Help articles an answer drew on (servers from SDK 0.9 on). */
|
|
88
|
+
articles?: {
|
|
89
|
+
id: string;
|
|
90
|
+
title: string;
|
|
91
|
+
}[];
|
|
92
|
+
}
|
|
93
|
+
/** A published help article in a list (the messenger's Help tab). */
|
|
94
|
+
interface ArticleSummary {
|
|
95
|
+
id: string;
|
|
96
|
+
title: string;
|
|
97
|
+
collection: string;
|
|
98
|
+
excerpt: string;
|
|
99
|
+
updatedAt: string;
|
|
100
|
+
}
|
|
101
|
+
/** A run of text inside an article block. Links are http(s), mailto or tel only. */
|
|
102
|
+
interface ArticleSpan {
|
|
103
|
+
text: string;
|
|
104
|
+
href?: string;
|
|
105
|
+
bold?: boolean;
|
|
106
|
+
italic?: boolean;
|
|
107
|
+
code?: boolean;
|
|
108
|
+
}
|
|
109
|
+
/** An article's content as blocks, written with textContent (never parsed as HTML). */
|
|
110
|
+
type ArticleBlock = {
|
|
111
|
+
type: "h2" | "h3" | "p" | "quote";
|
|
112
|
+
spans: ArticleSpan[];
|
|
113
|
+
} | {
|
|
114
|
+
type: "ul" | "ol";
|
|
115
|
+
items: ArticleSpan[][];
|
|
116
|
+
} | {
|
|
117
|
+
type: "code";
|
|
118
|
+
text: string;
|
|
119
|
+
} | {
|
|
120
|
+
type: "hr";
|
|
121
|
+
};
|
|
122
|
+
interface Article {
|
|
123
|
+
id: string;
|
|
124
|
+
title: string;
|
|
125
|
+
collection: string;
|
|
126
|
+
updatedAt: string;
|
|
127
|
+
blocks: ArticleBlock[];
|
|
128
|
+
}
|
|
129
|
+
/** The messenger's look and texts as set in MRRocket › Support › Messenger (servers from SDK 0.9 on). */
|
|
130
|
+
interface MessengerLook {
|
|
131
|
+
accent: string;
|
|
132
|
+
theme: "light" | "dark" | "auto";
|
|
133
|
+
position: "bottom-right" | "bottom-left";
|
|
134
|
+
title: string;
|
|
135
|
+
greeting: string;
|
|
136
|
+
label: string;
|
|
137
|
+
help: boolean;
|
|
138
|
+
sound: boolean;
|
|
139
|
+
preview: boolean;
|
|
140
|
+
askEmail: boolean;
|
|
141
|
+
}
|
|
142
|
+
/** The visitor's newest chat (open or closed) and its messages. */
|
|
143
|
+
interface ChatThread {
|
|
144
|
+
conversation: {
|
|
145
|
+
id: string;
|
|
146
|
+
status: "open" | "solved";
|
|
147
|
+
} | null;
|
|
148
|
+
messages: ChatMessage[];
|
|
149
|
+
/** The visitor gave an email already: the messenger stops asking. */
|
|
150
|
+
hasEmail: boolean;
|
|
151
|
+
}
|
|
152
|
+
interface Conn {
|
|
153
|
+
host: string;
|
|
154
|
+
apiKey: string;
|
|
155
|
+
distinctId: string;
|
|
156
|
+
user?: {
|
|
157
|
+
id?: string;
|
|
158
|
+
[key: string]: unknown;
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
/** The small fetch client behind the widgets. Every read takes an AbortSignal so unmounting cancels it. */
|
|
162
|
+
declare const createApi: (c: Conn) => {
|
|
163
|
+
list: (o: {
|
|
164
|
+
board?: string;
|
|
165
|
+
sort?: "top" | "new";
|
|
166
|
+
q?: string;
|
|
167
|
+
}, signal?: AbortSignal) => Promise<FeedbackList>;
|
|
168
|
+
post: (id: string, signal?: AbortSignal) => Promise<FeedbackPost>;
|
|
169
|
+
roadmap: (signal?: AbortSignal) => Promise<FeedbackRoadmap>;
|
|
170
|
+
changelog: (signal?: AbortSignal) => Promise<{
|
|
171
|
+
entries: ChangelogEntry[];
|
|
172
|
+
}>;
|
|
173
|
+
submit: (p: {
|
|
174
|
+
title: string;
|
|
175
|
+
body?: string;
|
|
176
|
+
board: string;
|
|
177
|
+
}) => Promise<FeedbackPost>;
|
|
178
|
+
vote: (id: string) => Promise<{
|
|
179
|
+
voted: boolean;
|
|
180
|
+
votes: number;
|
|
181
|
+
}>;
|
|
182
|
+
comments: (id: string, signal?: AbortSignal) => Promise<{
|
|
183
|
+
comments: FeedbackComment[];
|
|
184
|
+
}>;
|
|
185
|
+
comment: (id: string, body: string) => Promise<FeedbackComment>;
|
|
186
|
+
survey: (url: string, signal?: AbortSignal) => Promise<{
|
|
187
|
+
survey: SurveyDefinition | null;
|
|
188
|
+
}>;
|
|
189
|
+
seen: (id: string) => Promise<unknown>;
|
|
190
|
+
respond: (id: string, r: {
|
|
191
|
+
answers: Record<string, SurveyAnswer>;
|
|
192
|
+
completed: boolean;
|
|
193
|
+
seconds: number;
|
|
194
|
+
}) => Promise<unknown>;
|
|
195
|
+
chat: (signal?: AbortSignal) => Promise<ChatThread>;
|
|
196
|
+
sendChat: (m: {
|
|
197
|
+
body: string;
|
|
198
|
+
email?: string;
|
|
199
|
+
url?: string;
|
|
200
|
+
}) => Promise<ChatThread>;
|
|
201
|
+
articles: (q?: string, signal?: AbortSignal) => Promise<{
|
|
202
|
+
articles: ArticleSummary[];
|
|
203
|
+
}>;
|
|
204
|
+
article: (id: string, signal?: AbortSignal) => Promise<Article>;
|
|
205
|
+
messengerLook: (signal?: AbortSignal) => Promise<MessengerLook>;
|
|
206
|
+
rateArticle: (id: string, helpful: boolean) => Promise<{
|
|
207
|
+
counted: boolean;
|
|
208
|
+
}>;
|
|
209
|
+
};
|
|
210
|
+
type Api = ReturnType<typeof createApi>;
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* The cancel flow, onboarding and in-app messages (SDK 0.7.0): what MRRocket's config and `GET /api/sdk/inapp` serve,
|
|
214
|
+
* and one controller that decides what shows when and records what the person did. No DOM and no React: the web
|
|
215
|
+
* renderer (flows-ui.ts, loaded only when something shows) and the React Native one (native/flows-view.ts) draw
|
|
216
|
+
* `view()` and call the actions.
|
|
217
|
+
*
|
|
218
|
+
* What it records, as normal events under the SDK's analytics consent (nothing with consent "off"):
|
|
219
|
+
* - `$cancel_flow` `{action: "shown" | "answered" | "offer" | "finished", run, version, …}`. MRRocket turns a
|
|
220
|
+
* `finished` with `outcome: "saved"` into a save and with `outcome: "cancelled"` into a cancellation on the Churn page.
|
|
221
|
+
* MRRocket never changes a subscription: an accepted offer goes to the app's `onSave`, a confirmed cancel to its
|
|
222
|
+
* `onCancel`, and only after they succeed is the outcome recorded.
|
|
223
|
+
* - `$onboarding` `{flow, step?, action: "started" | "shown" | "completed" | "dismissed"}`.
|
|
224
|
+
* - `$inapp` `{message, journey, action: "shown" | "clicked" | "dismissed"}`; the journey moves the person on.
|
|
225
|
+
*/
|
|
226
|
+
|
|
227
|
+
type CancelOfferKind = "discount" | "pause" | "downgrade" | "contact";
|
|
228
|
+
/** What one answer of the survey offers before the confirmation. An answer without one goes straight to it. */
|
|
229
|
+
interface CancelOffer {
|
|
230
|
+
kind: CancelOfferKind;
|
|
231
|
+
headline: string;
|
|
232
|
+
/** Discount: percent off. */
|
|
233
|
+
percent?: number;
|
|
234
|
+
/** Discount: for how many months; pause: up to how many months. */
|
|
235
|
+
months?: number;
|
|
236
|
+
/** Downgrade: the plan to switch to, as MRRocket knows it from the payment provider. */
|
|
237
|
+
plan?: string;
|
|
238
|
+
planName?: string;
|
|
239
|
+
}
|
|
240
|
+
/** The product's live cancel flow (MRRocket › Churn › Cancel flow). */
|
|
241
|
+
interface CancelFlowConfig {
|
|
242
|
+
/** Grows with every publish. */
|
|
243
|
+
version: number;
|
|
244
|
+
question: string;
|
|
245
|
+
/** The survey's answers, in order. */
|
|
246
|
+
reasons: {
|
|
247
|
+
id: string;
|
|
248
|
+
label: string;
|
|
249
|
+
}[];
|
|
250
|
+
/** The offer per answer id. */
|
|
251
|
+
offers: Record<string, CancelOffer>;
|
|
252
|
+
confirm: {
|
|
253
|
+
title: string;
|
|
254
|
+
body: string;
|
|
255
|
+
button: string;
|
|
256
|
+
};
|
|
257
|
+
/**
|
|
258
|
+
* Who gets the survey and the offers: business customers only. Anyone else (a consumer, or a customer the app does
|
|
259
|
+
* not say) gets the plain confirmation, with nothing in the way of cancelling (§ 312k BGB).
|
|
260
|
+
*/
|
|
261
|
+
offersFor: "business";
|
|
262
|
+
}
|
|
263
|
+
type OnboardingStepKind = "tour" | "checklist" | "modal";
|
|
264
|
+
interface OnboardingStep {
|
|
265
|
+
id: string;
|
|
266
|
+
kind: OnboardingStepKind;
|
|
267
|
+
title: string;
|
|
268
|
+
body?: string;
|
|
269
|
+
button?: string;
|
|
270
|
+
/** Tour steps: the element they point at, marked `data-ck-target="<target>"` in the app. Without it: a card. */
|
|
271
|
+
target?: string;
|
|
272
|
+
/** Checklist items: the event that ticks them (`track("<event>")`). Without it the person ticks it themselves. */
|
|
273
|
+
event?: string;
|
|
274
|
+
}
|
|
275
|
+
/** A live onboarding flow's in-app steps (MRRocket › Conversion › Onboarding); its emails go out from MRRocket. */
|
|
276
|
+
interface OnboardingFlow {
|
|
277
|
+
id: string;
|
|
278
|
+
name: string;
|
|
279
|
+
/** When it starts: an event's words ("Signed up", "First export"), or "First launch" / "First visit". */
|
|
280
|
+
trigger: string;
|
|
281
|
+
steps: OnboardingStep[];
|
|
282
|
+
}
|
|
283
|
+
/** An in-app message a Lifecycle journey has for this person. */
|
|
284
|
+
interface InAppMessage {
|
|
285
|
+
id: string;
|
|
286
|
+
journey?: string;
|
|
287
|
+
title: string;
|
|
288
|
+
body?: string;
|
|
289
|
+
button?: string;
|
|
290
|
+
/** Where the button goes (http(s) or a path of the app). */
|
|
291
|
+
url?: string;
|
|
292
|
+
style: "banner" | "modal";
|
|
293
|
+
}
|
|
294
|
+
interface CancelFlowResult {
|
|
295
|
+
/** "cancelled": confirmed; "saved": took the offer; "kept": closed the dialog without cancelling. */
|
|
296
|
+
outcome: "cancelled" | "saved" | "kept";
|
|
297
|
+
reason?: string;
|
|
298
|
+
reasonLabel?: string;
|
|
299
|
+
offer?: CancelOffer;
|
|
300
|
+
/** What the customer wrote on the confirmation, if anything. */
|
|
301
|
+
comment?: string;
|
|
302
|
+
/** This run's id, the same as in the events. */
|
|
303
|
+
run: string;
|
|
304
|
+
}
|
|
305
|
+
interface CancelFlowOptions {
|
|
306
|
+
/**
|
|
307
|
+
* "business" shows the survey and the offers; anything else (the default) only the plain confirmation, so a
|
|
308
|
+
* consumer can always cancel in one step (§ 312k BGB).
|
|
309
|
+
*/
|
|
310
|
+
customer?: "business" | "consumer";
|
|
311
|
+
/** The customer's current price, to show what a discount costs (`{ amount: 29, currency: "EUR" }`). */
|
|
312
|
+
price?: {
|
|
313
|
+
amount: number;
|
|
314
|
+
currency: string;
|
|
315
|
+
interval?: "month" | "year";
|
|
316
|
+
};
|
|
317
|
+
/** The customer confirmed: cancel the subscription in your code. Throwing keeps the dialog open with an error. */
|
|
318
|
+
onCancel?: (result: CancelFlowResult) => unknown;
|
|
319
|
+
/** The customer took an offer: apply it in your code (coupon, pause, plan change). Throwing keeps the dialog open. */
|
|
320
|
+
onSave?: (result: CancelFlowResult) => unknown;
|
|
321
|
+
/** Closed without cancelling or taking an offer. */
|
|
322
|
+
onClose?: (result: CancelFlowResult) => void;
|
|
323
|
+
}
|
|
324
|
+
/** What a renderer draws. */
|
|
325
|
+
type FlowView = {
|
|
326
|
+
type: "cancel";
|
|
327
|
+
screen: "survey" | "offer" | "confirm";
|
|
328
|
+
flow: CancelFlowConfig;
|
|
329
|
+
/** The answer picked on the survey. */
|
|
330
|
+
reason?: string;
|
|
331
|
+
offer?: CancelOffer;
|
|
332
|
+
price?: CancelFlowOptions["price"];
|
|
333
|
+
busy: boolean;
|
|
334
|
+
error?: string;
|
|
335
|
+
/** The step for the dots, 1 to `steps`. */
|
|
336
|
+
step: number;
|
|
337
|
+
steps: number;
|
|
338
|
+
} | {
|
|
339
|
+
type: "step";
|
|
340
|
+
flow: OnboardingFlow;
|
|
341
|
+
step: OnboardingStep;
|
|
342
|
+
index: number;
|
|
343
|
+
total: number;
|
|
344
|
+
last: boolean;
|
|
345
|
+
} | {
|
|
346
|
+
type: "checklist";
|
|
347
|
+
flow: OnboardingFlow;
|
|
348
|
+
items: {
|
|
349
|
+
step: OnboardingStep;
|
|
350
|
+
done: boolean;
|
|
351
|
+
}[];
|
|
352
|
+
} | {
|
|
353
|
+
type: "message";
|
|
354
|
+
message: InAppMessage;
|
|
355
|
+
};
|
|
356
|
+
interface FlowsController {
|
|
357
|
+
setConfig(config: CockpitConfig | null): void;
|
|
358
|
+
/** The person changed (identify, reset, consent): loads their messages and onboarding progress. */
|
|
359
|
+
refresh(): Promise<void>;
|
|
360
|
+
/** An event the app recorded: starts flows whose trigger it is and ticks checklist items. */
|
|
361
|
+
onEvent(name: string): void;
|
|
362
|
+
openCancelFlow(options?: CancelFlowOptions): Promise<CancelFlowResult>;
|
|
363
|
+
/** Starts an onboarding flow now (the first live one without an id). False when there is none to start. */
|
|
364
|
+
startOnboarding(id?: string): boolean;
|
|
365
|
+
view(): FlowView | null;
|
|
366
|
+
subscribe(listener: () => void): () => void;
|
|
367
|
+
/** `accept(comment)`: a "Talk to us" offer sends what the customer wrote with it. */
|
|
368
|
+
cancel: {
|
|
369
|
+
pick(reason: string): void;
|
|
370
|
+
next(): void;
|
|
371
|
+
accept(comment?: string): void;
|
|
372
|
+
decline(): void;
|
|
373
|
+
confirm(comment?: string): void;
|
|
374
|
+
close(): void;
|
|
375
|
+
};
|
|
376
|
+
onboarding: {
|
|
377
|
+
next(): void;
|
|
378
|
+
check(stepId: string): void;
|
|
379
|
+
dismiss(): void;
|
|
380
|
+
};
|
|
381
|
+
message: {
|
|
382
|
+
click(): void;
|
|
383
|
+
dismiss(): void;
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
|
|
4
387
|
/**
|
|
5
388
|
* The part of the SDK that runs anywhere: experiment config, variant assignment, preview links and event shapes.
|
|
6
389
|
* No React, no browser APIs, so the server helper, the proxy helper and the client share it.
|
|
7
390
|
*/
|
|
391
|
+
|
|
8
392
|
type VariantId = string;
|
|
9
393
|
/** This build of the SDK. Sent with the config request so MRRocket knows what the site runs (error tracking, flags). */
|
|
10
|
-
declare const SDK_VERSION = "0.
|
|
394
|
+
declare const SDK_VERSION = "0.9.0";
|
|
11
395
|
/** One variant of an experiment. `changes` replaces texts that the page marks with `<Text id>`. */
|
|
12
396
|
interface VariantConfig {
|
|
13
397
|
id: VariantId;
|
|
14
398
|
/** Share of traffic, 0 to 1. The weights of an experiment add up to 1. */
|
|
15
399
|
weight: number;
|
|
16
400
|
changes?: Record<string, string>;
|
|
401
|
+
/**
|
|
402
|
+
* A redirect test: where this variant sends the visitor instead of the test's page (a path like "/pricing-b" or a
|
|
403
|
+
* full address). Control has none and stays. SDK 0.7.0+.
|
|
404
|
+
*/
|
|
405
|
+
url?: string;
|
|
17
406
|
}
|
|
18
407
|
interface ExperimentConfig {
|
|
19
408
|
/** The experiment's key, the same as in Cockpit. */
|
|
@@ -23,6 +412,15 @@ interface ExperimentConfig {
|
|
|
23
412
|
variants: VariantConfig[];
|
|
24
413
|
/** A winner that shipped: everyone gets it, and nobody is assigned anymore. */
|
|
25
414
|
winner?: VariantId;
|
|
415
|
+
/** A redirect test: the path of the page it runs on ("/pricing"). Visitors there are sent to their variant's `url`. */
|
|
416
|
+
path?: string;
|
|
417
|
+
}
|
|
418
|
+
/** A page redirect set in MRRocket (Conversion › Landing pages › Redirect): everyone on `from` goes to `to`. SDK 0.7.0+. */
|
|
419
|
+
interface RedirectConfig {
|
|
420
|
+
/** A path of the site, like "/old-pricing". */
|
|
421
|
+
from: string;
|
|
422
|
+
/** A path or a full address. */
|
|
423
|
+
to: string;
|
|
26
424
|
}
|
|
27
425
|
interface CockpitConfig {
|
|
28
426
|
/** The product the public key belongs to. */
|
|
@@ -36,6 +434,20 @@ interface CockpitConfig {
|
|
|
36
434
|
replay?: ReplayConfig;
|
|
37
435
|
/** Feature flags of the product in Production (MRRocket › Build › Feature flags), evaluated by `useFlag` and `getFlag`. */
|
|
38
436
|
flags?: FlagConfig[];
|
|
437
|
+
/**
|
|
438
|
+
* Published copy for texts the site marks (`<Text id>`, `data-ck-text`): a landing page's headline, subheadline and
|
|
439
|
+
* button (`pricing.headline` …) and a paywall's (`paywall.<placement>.headline` …) as published in MRRocket. A
|
|
440
|
+
* running test's variant changes them on top. Missing when nothing is published. SDK 0.5.0+.
|
|
441
|
+
*/
|
|
442
|
+
texts?: Record<string, string>;
|
|
443
|
+
/** The product's live cancel flow (MRRocket › Churn › Cancel flow), for `cancelFlow.open()`. SDK 0.7.0+. */
|
|
444
|
+
cancelFlow?: CancelFlowConfig;
|
|
445
|
+
/** The in-app steps of live onboarding flows (tours, checklists, modals). SDK 0.7.0+. */
|
|
446
|
+
onboarding?: OnboardingFlow[];
|
|
447
|
+
/** A live Lifecycle journey has in-app messages: signed-in people ask `/api/sdk/inapp` for theirs. SDK 0.7.0+. */
|
|
448
|
+
messages?: boolean;
|
|
449
|
+
/** Page redirects set in MRRocket; the SDK sends visitors on before the page shows (`redirectFor`). SDK 0.7.0+. */
|
|
450
|
+
redirects?: RedirectConfig[];
|
|
39
451
|
}
|
|
40
452
|
/** One condition of a flag's audience, on a property of the person (`identify(id, props)`), the id or the page. */
|
|
41
453
|
interface FlagCondition {
|
|
@@ -118,6 +530,14 @@ interface AppContext {
|
|
|
118
530
|
locale?: string;
|
|
119
531
|
}
|
|
120
532
|
|
|
533
|
+
/**
|
|
534
|
+
* The React Native client without React: the event queue (batched, persisted for offline use, retried with backoff),
|
|
535
|
+
* the app lifecycle (`$app_open`, `$app_background`, a new session after 30 minutes away), screens, identity and
|
|
536
|
+
* consent, the cached config for flags and experiments, install attribution from the first open's deep link, and error
|
|
537
|
+
* capture. Everything the platform gives (storage, AppState, ErrorUtils, device info, fetch) comes in as `deps`, so
|
|
538
|
+
* it runs in tests without React Native; `platform.ts` builds the real ones.
|
|
539
|
+
*/
|
|
540
|
+
|
|
121
541
|
/**
|
|
122
542
|
* What the app may send and store.
|
|
123
543
|
* - "anonymous" (default): no id is stored on the device. Events go without a person id until `identify()` (MRRocket
|
|
@@ -147,6 +567,16 @@ interface MRRocketOptions {
|
|
|
147
567
|
maxQueue?: number;
|
|
148
568
|
/** Log what the SDK does to the console. */
|
|
149
569
|
debug?: boolean;
|
|
570
|
+
/** Onboarding flows start on their own when the person does their trigger (default true). False: only `startOnboarding()`. */
|
|
571
|
+
onboarding?: boolean;
|
|
572
|
+
/** Taps go to Heatmaps as clicks on the screen they happened on (default true; `MRRocketProvider` captures them). */
|
|
573
|
+
heatmaps?: boolean;
|
|
574
|
+
/**
|
|
575
|
+
* The person agreed to session recordings (default false; ask them first). Needs `react-native-view-shot` and the
|
|
576
|
+
* product's recordings switched on in MRRocket. No frame while the keyboard is open; wrap private views in
|
|
577
|
+
* `<MRRocketMask>`. Change it later with `setReplay`.
|
|
578
|
+
*/
|
|
579
|
+
replay?: boolean;
|
|
150
580
|
}
|
|
151
581
|
/** AsyncStorage's shape. */
|
|
152
582
|
interface KeyValueStorage {
|
|
@@ -154,11 +584,29 @@ interface KeyValueStorage {
|
|
|
154
584
|
setItem(key: string, value: string): Promise<void>;
|
|
155
585
|
removeItem(key: string): Promise<void>;
|
|
156
586
|
}
|
|
587
|
+
interface RegisterForPushOptions {
|
|
588
|
+
/** Ask for the permission when it was not decided yet (default true). False: only register when already allowed. */
|
|
589
|
+
ask?: boolean;
|
|
590
|
+
/** Your EAS project id; default: the one in your app config (`expo-constants`). */
|
|
591
|
+
projectId?: string;
|
|
592
|
+
}
|
|
593
|
+
type NativePushStatus = "registered" | "denied" | "not-asked" | "unavailable" | "not-signed-in" | "error";
|
|
594
|
+
interface NativePushResult {
|
|
595
|
+
status: NativePushStatus;
|
|
596
|
+
/** The Expo push token, once registered. */
|
|
597
|
+
token?: string;
|
|
598
|
+
/** Why it is unavailable or failed. */
|
|
599
|
+
reason?: string;
|
|
600
|
+
}
|
|
157
601
|
/** What the app (and the React hooks) use. */
|
|
158
602
|
interface MRRocketClient {
|
|
159
603
|
track(event: string, props?: Record<string, unknown>): void;
|
|
160
604
|
/** A screen view: a route name ("Settings") or an Expo Router path ("/settings"). */
|
|
161
605
|
screen(name: string, props?: Record<string, unknown>): void;
|
|
606
|
+
/** A tap at screen points (x, y) for Heatmaps, on the current screen; `MRRocketProvider` calls it. */
|
|
607
|
+
tap(x: number, y: number): void;
|
|
608
|
+
/** The person's answer to session recordings (`replay` in the options); false stops and forgets what was not sent. */
|
|
609
|
+
setReplay(on: boolean): void;
|
|
162
610
|
identify(id: string, props?: Record<string, unknown>): void;
|
|
163
611
|
/** Forgets the signed-in person (sign-out): a new anonymous id and a new session. */
|
|
164
612
|
reset(): void;
|
|
@@ -172,6 +620,35 @@ interface MRRocketClient {
|
|
|
172
620
|
peekVariant(key: string): VariantId;
|
|
173
621
|
/** Records that the person saw `variant` of `key`, once per screen. */
|
|
174
622
|
expose(key: string, variant: VariantId): void;
|
|
623
|
+
/**
|
|
624
|
+
* The copy for text `id` as published in MRRocket (a paywall's `paywall.<placement>.headline`, an onboarding title …)
|
|
625
|
+
* with this person's experiment variant applied on top, the same rules as `<Text id>` on the web; `fallback` (your
|
|
626
|
+
* own words) while nothing is published or the config is unknown. Records the exposure to every test that changes
|
|
627
|
+
* `id`, once per screen.
|
|
628
|
+
*/
|
|
629
|
+
getText(id: string, fallback: string): string;
|
|
630
|
+
/** The text without recording anything (render code); undefined when MRRocket has none. Pair it with `exposeText`. */
|
|
631
|
+
peekText(id: string): string | undefined;
|
|
632
|
+
/** Records that the person saw text `id`: an exposure to each test that changes it, once per screen. */
|
|
633
|
+
exposeText(id: string): void;
|
|
634
|
+
/**
|
|
635
|
+
* Shows the cancel flow built in MRRocket › Churn (drawn by `<MRRocketProvider>`), resolves with what the customer
|
|
636
|
+
* did. MRRocket never changes the subscription: your `onCancel` and `onSave` do.
|
|
637
|
+
*/
|
|
638
|
+
openCancelFlow(options?: CancelFlowOptions): Promise<CancelFlowResult>;
|
|
639
|
+
/** Starts an onboarding flow now (the first live one without an id). False when there is none. */
|
|
640
|
+
startOnboarding(id?: string): boolean;
|
|
641
|
+
/**
|
|
642
|
+
* Push notifications from your Lifecycle journeys for the signed-in person (call `identify` first). Asks the
|
|
643
|
+
* permission (unless `ask: false`), gets the Expo push token and sends it to MRRocket. Needs `expo-notifications`.
|
|
644
|
+
* Safe to call on every start: an existing token is sent again without asking. Opens of MRRocket's notifications
|
|
645
|
+
* are counted from then on.
|
|
646
|
+
*/
|
|
647
|
+
registerForPush(options?: RegisterForPushOptions): Promise<NativePushResult>;
|
|
648
|
+
/** Removes this device's token for the signed-in person (sign-out does it on its own in `reset`). */
|
|
649
|
+
unregisterForPush(): Promise<boolean>;
|
|
650
|
+
/** The cancel flow, onboarding and messages for a renderer (the provider's, or your own). */
|
|
651
|
+
flows: FlowsController;
|
|
175
652
|
/** Sends what is queued now. */
|
|
176
653
|
flush(): Promise<void>;
|
|
177
654
|
/** Resolves once stored state and the config (cached or fetched) are known. */
|
|
@@ -179,6 +656,23 @@ interface MRRocketClient {
|
|
|
179
656
|
isReady(): boolean;
|
|
180
657
|
getDistinctId(): string;
|
|
181
658
|
getConsent(): NativeConsent;
|
|
659
|
+
/**
|
|
660
|
+
* The client of the SDK's widget API (surveys, feedback, the messenger) for the person now: their id, and the name and
|
|
661
|
+
* email given to identify (or `as`, typed into a widget). Null while the consent is off or without a key.
|
|
662
|
+
*/
|
|
663
|
+
api(as?: {
|
|
664
|
+
name?: string;
|
|
665
|
+
email?: string;
|
|
666
|
+
}): Api | null;
|
|
667
|
+
/** The signed-in person (identify): their id, and the name and email given there. Undefined before identify. */
|
|
668
|
+
getUser(): {
|
|
669
|
+
id: string;
|
|
670
|
+
name?: string;
|
|
671
|
+
email?: string;
|
|
672
|
+
} | undefined;
|
|
673
|
+
/** Surveys answered or closed on this device: not shown again (kept on the device only with "persistent"). */
|
|
674
|
+
isSurveyDone(id: string): boolean;
|
|
675
|
+
markSurveyDone(id: string): void;
|
|
182
676
|
getConfig(): CockpitConfig | null;
|
|
183
677
|
/** For React: called after every change flags, variants or the consent depend on. Returns the unsubscribe. */
|
|
184
678
|
subscribe(listener: () => void): () => void;
|
|
@@ -192,6 +686,93 @@ interface MRRocketClient {
|
|
|
192
686
|
/** The name of the screen a React Navigation state shows: the focused route, followed into nested navigators. */
|
|
193
687
|
declare const activeRouteName: (state: unknown) => string | undefined;
|
|
194
688
|
|
|
689
|
+
interface NativeAppearance {
|
|
690
|
+
theme?: "light" | "dark" | "auto";
|
|
691
|
+
accent?: string;
|
|
692
|
+
}
|
|
693
|
+
declare const MRRocketFlows: ({ flows, appearance }: {
|
|
694
|
+
flows: FlowsController;
|
|
695
|
+
appearance?: NativeAppearance;
|
|
696
|
+
}) => react.FunctionComponentElement<Record<string, unknown>> | null;
|
|
697
|
+
|
|
698
|
+
interface Palette {
|
|
699
|
+
accent: string;
|
|
700
|
+
bg: string;
|
|
701
|
+
fg: string;
|
|
702
|
+
muted: string;
|
|
703
|
+
soft: string;
|
|
704
|
+
line: string;
|
|
705
|
+
danger: string;
|
|
706
|
+
}
|
|
707
|
+
/** Asks the person the survey MRRocket picks for them, a few seconds after start and again for a new person. */
|
|
708
|
+
declare const MRRocketSurveys: ({ client, appearance }: {
|
|
709
|
+
client: MRRocketClient;
|
|
710
|
+
appearance?: NativeAppearance;
|
|
711
|
+
}) => react.FunctionComponentElement<{
|
|
712
|
+
survey: SurveyDefinition;
|
|
713
|
+
api: Api;
|
|
714
|
+
p: Palette;
|
|
715
|
+
onDone: () => void;
|
|
716
|
+
}> | null;
|
|
717
|
+
/** Opens the feedback sheet: the top requests with votes, and a form to suggest one. */
|
|
718
|
+
declare const useFeedback: () => {
|
|
719
|
+
open: () => void;
|
|
720
|
+
close: () => void;
|
|
721
|
+
};
|
|
722
|
+
interface NativeFeedbackOptions {
|
|
723
|
+
/** The sheet's title. Default "Feedback". */
|
|
724
|
+
title?: string;
|
|
725
|
+
}
|
|
726
|
+
declare const MRRocketFeedback: ({ client, appearance, options }: {
|
|
727
|
+
client: MRRocketClient;
|
|
728
|
+
appearance?: NativeAppearance;
|
|
729
|
+
options?: NativeFeedbackOptions;
|
|
730
|
+
}) => react.FunctionComponentElement<{
|
|
731
|
+
client: MRRocketClient;
|
|
732
|
+
p: Palette;
|
|
733
|
+
title: string;
|
|
734
|
+
}> | null;
|
|
735
|
+
type MsgView = "home" | "messages" | "help" | {
|
|
736
|
+
article: string;
|
|
737
|
+
};
|
|
738
|
+
/** Opens (on Home, a tab or `{ article: id }`), closes or toggles the messenger. */
|
|
739
|
+
declare const useMessenger: () => {
|
|
740
|
+
open: (view?: MsgView) => void;
|
|
741
|
+
close: () => void;
|
|
742
|
+
toggle: () => void;
|
|
743
|
+
};
|
|
744
|
+
interface NativeMessengerOptions {
|
|
745
|
+
/** A round chat button bottom right (default false: open it with `useMessenger().open()` from your own button). */
|
|
746
|
+
launcher?: boolean;
|
|
747
|
+
title?: string;
|
|
748
|
+
/** The big line on Home and the first line of an empty chat. */
|
|
749
|
+
greeting?: string;
|
|
750
|
+
/** Ask people the app did not identify with an email for an email (optional for them). Default true. */
|
|
751
|
+
askEmail?: boolean;
|
|
752
|
+
/** The Help tab with your published help articles (default true; hidden while there are none). */
|
|
753
|
+
help?: boolean;
|
|
754
|
+
/** A banner at the top when an answer arrives while the messenger is closed (default true). */
|
|
755
|
+
preview?: boolean;
|
|
756
|
+
/** A light haptic when an answer arrives (default true; needs expo-haptics). */
|
|
757
|
+
haptics?: boolean;
|
|
758
|
+
}
|
|
759
|
+
declare const MRRocketMessenger: ({ client, appearance, options: given }: {
|
|
760
|
+
client: MRRocketClient;
|
|
761
|
+
appearance?: NativeAppearance;
|
|
762
|
+
options?: NativeMessengerOptions;
|
|
763
|
+
}) => react.FunctionComponentElement<Record<string, unknown>> | null;
|
|
764
|
+
|
|
765
|
+
/**
|
|
766
|
+
* Hides what it wraps in session recordings: its area is painted black on every frame before the frame is stored. Use
|
|
767
|
+
* it for anything private on screen (balances, addresses, messages). Text fields need no wrapper: nothing is recorded
|
|
768
|
+
* while the keyboard is open.
|
|
769
|
+
*
|
|
770
|
+
* <MRRocketMask><Text>{iban}</Text></MRRocketMask>
|
|
771
|
+
*/
|
|
772
|
+
declare const MRRocketMask: ({ children, style }: {
|
|
773
|
+
children?: ReactNode;
|
|
774
|
+
style?: unknown;
|
|
775
|
+
}) => react.FunctionComponentElement<Record<string, unknown>>;
|
|
195
776
|
/**
|
|
196
777
|
* The SDK's client outside React (a background task, a store, an API layer): the one the provider made, or a new one.
|
|
197
778
|
* One client per app; a second call returns the first.
|
|
@@ -208,6 +789,24 @@ interface MRRocketProviderProps extends Partial<MRRocketOptions> {
|
|
|
208
789
|
storage?: KeyValueStorage | null;
|
|
209
790
|
/** A client you made with createMRRocket; the other props are then ignored. */
|
|
210
791
|
client?: MRRocketClient;
|
|
792
|
+
/**
|
|
793
|
+
* Draw the cancel flow, onboarding and in-app messages (default true). False: draw `client.flows` yourself, or
|
|
794
|
+
* place `<MRRocketFlows flows={client.flows} />` where you want it.
|
|
795
|
+
*/
|
|
796
|
+
flows?: boolean;
|
|
797
|
+
/** The look of those dialogs and the widgets: `{ theme: "light" | "dark" | "auto", accent: "#0f766e" }`. */
|
|
798
|
+
appearance?: NativeAppearance;
|
|
799
|
+
/** Show the live in-app survey MRRocket picks for the person, a few seconds after start (default true). */
|
|
800
|
+
surveys?: boolean;
|
|
801
|
+
/** The chat with your team, opened with `useMessenger().open()`; `{ launcher: true }` adds a round button. False: none. */
|
|
802
|
+
messenger?: NativeMessengerOptions | false;
|
|
803
|
+
/** The feedback sheet opened with `useFeedback().open()` (`{ title }`). False: none. */
|
|
804
|
+
feedback?: NativeFeedbackOptions | false;
|
|
805
|
+
/**
|
|
806
|
+
* Taps for Heatmaps (default true). The provider then wraps the app in one `View` with `flex: 1` to see them; false
|
|
807
|
+
* leaves the app as it is.
|
|
808
|
+
*/
|
|
809
|
+
heatmaps?: boolean;
|
|
211
810
|
children?: ReactNode;
|
|
212
811
|
}
|
|
213
812
|
/**
|
|
@@ -215,7 +814,7 @@ interface MRRocketProviderProps extends Partial<MRRocketOptions> {
|
|
|
215
814
|
* starts the SDK: lifecycle events, the event queue, flags and experiments, error capture. Changing `consent` later
|
|
216
815
|
* calls setConsent.
|
|
217
816
|
*/
|
|
218
|
-
declare const MRRocketProvider: ({ client: given, children, consent, ...options }: MRRocketProviderProps) => react.FunctionComponentElement<react.ProviderProps<MRRocketClient | null>>;
|
|
817
|
+
declare const MRRocketProvider: ({ client: given, children, consent, flows, appearance, surveys, messenger, feedback, heatmaps, ...options }: MRRocketProviderProps) => react.FunctionComponentElement<react.ProviderProps<MRRocketClient | null>>;
|
|
219
818
|
/**
|
|
220
819
|
* `track`, `screen`, `identify`, `reset`, `setConsent`, `captureError`, `flush`, the visitor id, the consent and whether
|
|
221
820
|
* flags and experiments have loaded.
|
|
@@ -226,12 +825,40 @@ declare const useMRRocket: () => {
|
|
|
226
825
|
identify: (id: string, props?: Record<string, unknown>) => void;
|
|
227
826
|
reset: () => void;
|
|
228
827
|
setConsent: (consent: NativeConsent) => void;
|
|
828
|
+
setReplay: (on: boolean) => void;
|
|
229
829
|
captureError: (error: unknown) => void;
|
|
230
830
|
flush: () => Promise<void>;
|
|
231
831
|
distinctId: string;
|
|
232
832
|
consent: NativeConsent;
|
|
233
833
|
ready: boolean;
|
|
234
834
|
};
|
|
835
|
+
/**
|
|
836
|
+
* The cancel flow built in MRRocket › Churn › Cancel flow. Call `open` from your Cancel button; the provider draws it.
|
|
837
|
+
* MRRocket never changes the subscription: your `onCancel` and `onSave` do (RevenueCat, your server, the store's
|
|
838
|
+
* subscription page).
|
|
839
|
+
*
|
|
840
|
+
* const cancelFlow = useCancelFlow();
|
|
841
|
+
* <Button title="Cancel subscription" onPress={() => cancelFlow.open({ customer: "consumer", onCancel: openStoreSubscriptions })} />
|
|
842
|
+
*/
|
|
843
|
+
declare const useCancelFlow: () => {
|
|
844
|
+
open: (options?: CancelFlowOptions) => Promise<CancelFlowResult>;
|
|
845
|
+
};
|
|
846
|
+
/**
|
|
847
|
+
* Push notifications from your Lifecycle journeys (needs `expo-notifications`). After sign-in (`identify`), call
|
|
848
|
+
* `register()`: it asks the permission, gets the Expo push token and sends it to MRRocket. Sign-out (`reset`) takes the
|
|
849
|
+
* token back on its own.
|
|
850
|
+
*
|
|
851
|
+
* const push = usePush();
|
|
852
|
+
* useEffect(() => { if (user) void push.register(); }, [user]);
|
|
853
|
+
*/
|
|
854
|
+
declare const usePush: () => {
|
|
855
|
+
register: MRRocketClient["registerForPush"];
|
|
856
|
+
unregister: MRRocketClient["unregisterForPush"];
|
|
857
|
+
};
|
|
858
|
+
/** Starts an onboarding flow now (the first live one without an id), whatever its trigger. */
|
|
859
|
+
declare const useOnboarding: () => {
|
|
860
|
+
start: (id?: string) => boolean;
|
|
861
|
+
};
|
|
235
862
|
/** A feature flag from MRRocket › Build › Feature flags: true while it is on for this person; false while off, unknown or loading. */
|
|
236
863
|
declare const useFlag: (key: string) => boolean;
|
|
237
864
|
/** The variant of a multivariate flag ("control", "test" …), or null while it is off. */
|
|
@@ -241,6 +868,16 @@ declare const useFlagVariant: (key: string) => string | null;
|
|
|
241
868
|
* cold start, so the first screen is already stable). Records the exposure once per screen.
|
|
242
869
|
*/
|
|
243
870
|
declare const useVariant: (key: string) => VariantId;
|
|
871
|
+
/**
|
|
872
|
+
* Copy MRRocket can change without an app update: the text published for `id` (a paywall's
|
|
873
|
+
* `paywall.<placement>.headline`, `.body`, `.cta`), with this person's variant of a running text test on top,
|
|
874
|
+
* the same rules as `<Text id>` on the web. Write your own words as `fallback`: they show while nothing is published
|
|
875
|
+
* and on a first start before the config arrives. Records the exposure to every test that changes `id`, once per screen.
|
|
876
|
+
*
|
|
877
|
+
* const headline = useText("paywall.onboarding.headline", "Unlock everything");
|
|
878
|
+
* <Text style={styles.title}>{headline}</Text>
|
|
879
|
+
*/
|
|
880
|
+
declare const useText: (id: string, fallback: string) => string;
|
|
244
881
|
/**
|
|
245
882
|
* Screen views for Expo Router: one `$screen` per path ("/settings", "/product/[id]" as its real path). Call it in a
|
|
246
883
|
* component inside both the router and MRRocketProvider, for example the root layout's child.
|
|
@@ -256,4 +893,4 @@ declare const useExpoRouterTracking: () => void;
|
|
|
256
893
|
*/
|
|
257
894
|
declare const useNavigationTracking: () => (state: unknown) => void;
|
|
258
895
|
|
|
259
|
-
export { type AppContext, type CockpitConfig, type FlagConfig, type KeyValueStorage, type MRRocketClient, type MRRocketOptions, MRRocketProvider, type MRRocketProviderProps, type NativeConsent, SDK_VERSION, type VariantId, activeRouteName, createMRRocket, getMRRocket, useExpoRouterTracking, useFlag, useFlagVariant, useMRRocket, useNavigationTracking, useVariant };
|
|
896
|
+
export { type AppContext, type CancelFlowConfig, type CancelFlowOptions, type CancelFlowResult, type CancelOffer, type ChatMessage, type ChatThread, type CockpitConfig, type FeedbackPost, type FlagConfig, type FlowView, type InAppMessage, type KeyValueStorage, type MRRocketClient, MRRocketFeedback, MRRocketFlows, MRRocketMask, MRRocketMessenger, type MRRocketOptions, MRRocketProvider, type MRRocketProviderProps, MRRocketSurveys, type NativeAppearance, type NativeConsent, type NativeFeedbackOptions, type NativeMessengerOptions, type NativePushResult, type NativePushStatus, type OnboardingFlow, type OnboardingStep, type RegisterForPushOptions, SDK_VERSION, type SurveyDefinition, type VariantId, activeRouteName, createMRRocket, getMRRocket, useCancelFlow, useExpoRouterTracking, useFeedback, useFlag, useFlagVariant, useMRRocket, useMessenger, useNavigationTracking, useOnboarding, usePush, useText, useVariant };
|