@mrrocket/sdk 0.17.0 → 0.21.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.
Files changed (69) hide show
  1. package/CHANGELOG.md +30 -1
  2. package/README.md +24 -1
  3. package/dist/api-client.d.ts +28 -4
  4. package/dist/api-client.js +30 -13
  5. package/dist/api-client.js.map +1 -1
  6. package/dist/browser/mrrocket-flows.js +15 -3
  7. package/dist/browser/mrrocket-messenger.js +38 -5
  8. package/dist/browser/mrrocket.js +1 -1
  9. package/dist/browser.d.ts +2 -2
  10. package/dist/browser.js +2 -1
  11. package/dist/browser.js.map +1 -1
  12. package/dist/client.d.ts +28 -3
  13. package/dist/client.js +37 -5
  14. package/dist/client.js.map +1 -1
  15. package/dist/context.d.ts +3 -1
  16. package/dist/context.js.map +1 -1
  17. package/dist/core.d.ts +7 -1
  18. package/dist/core.js +1 -1
  19. package/dist/core.js.map +1 -1
  20. package/dist/feedback.js +161 -119
  21. package/dist/feedback.js.map +1 -1
  22. package/dist/finish-web.d.ts +18 -0
  23. package/dist/finish-web.js +139 -0
  24. package/dist/finish-web.js.map +1 -0
  25. package/dist/flows-ui.d.ts +1 -10
  26. package/dist/flows-ui.js +175 -48
  27. package/dist/flows-ui.js.map +1 -1
  28. package/dist/flows-web.d.ts +8 -1
  29. package/dist/flows-web.js +10 -1
  30. package/dist/flows-web.js.map +1 -1
  31. package/dist/flows.d.ts +193 -9
  32. package/dist/flows.js +284 -38
  33. package/dist/flows.js.map +1 -1
  34. package/dist/i18n.d.ts +22 -0
  35. package/dist/i18n.js +74 -0
  36. package/dist/i18n.js.map +1 -0
  37. package/dist/icons.d.ts +24 -0
  38. package/dist/icons.js +61 -0
  39. package/dist/icons.js.map +1 -0
  40. package/dist/index.d.ts +6 -2
  41. package/dist/index.js +8 -0
  42. package/dist/index.js.map +1 -1
  43. package/dist/messenger-ui.d.ts +9 -3
  44. package/dist/messenger-ui.js +388 -191
  45. package/dist/messenger-ui.js.map +1 -1
  46. package/dist/messenger.d.ts +3 -1
  47. package/dist/messenger.js +3 -2
  48. package/dist/messenger.js.map +1 -1
  49. package/dist/onboarding-state.d.ts +23 -0
  50. package/dist/onboarding-state.js +43 -0
  51. package/dist/onboarding-state.js.map +1 -0
  52. package/dist/paywall.js +2 -1
  53. package/dist/paywall.js.map +1 -1
  54. package/dist/react-native/index.d.cts +239 -19
  55. package/dist/react-native/index.d.ts +239 -19
  56. package/dist/react-native/index.js +1305 -518
  57. package/dist/react-native/index.js.map +1 -1
  58. package/dist/server.d.ts +4 -2
  59. package/dist/server.js +2 -2
  60. package/dist/server.js.map +1 -1
  61. package/dist/styles-css.d.ts +1 -1
  62. package/dist/styles-css.js +35 -2
  63. package/dist/styles-css.js.map +1 -1
  64. package/dist/survey.js +18 -14
  65. package/dist/survey.js.map +1 -1
  66. package/dist/ui.d.ts +2 -0
  67. package/dist/ui.js +15 -12
  68. package/dist/ui.js.map +1 -1
  69. package/package.json +6 -3
package/dist/flows.d.ts CHANGED
@@ -12,7 +12,9 @@
12
12
  * - `$onboarding` `{flow, step?, action: "started" | "shown" | "completed" | "dismissed"}`; since 0.11.0 a wait records
13
13
  * "shown" when the person reaches it and "completed" when it is over, a condition `{action: "answered", answer: "yes"
14
14
  * | "no"}` once it is decided; since 0.17.0 a tour a checklist task started records `{action: "started", from}` with
15
- * the checklist's id.
15
+ * the checklist's id; since 0.18.0 a question records `{kind: "question", action: "completed", question, answer,
16
+ * label}` (the question's key, the option's id or the typed text, the option's words), which MRRocket keeps on the
17
+ * contact, and a checklist task that opens something `{action: "opened", opens}`.
16
18
  * - `$inapp` `{message, journey, action: "shown" | "clicked" | "dismissed"}`; the journey moves the person on.
17
19
  */
18
20
  import type { CockpitConfig } from "./core.js";
@@ -37,8 +39,10 @@ export interface CancelOffer {
37
39
  /** 0.15.0: a second question after an answer ("What would be a fair price?"); no answers means a free text. */
38
40
  export interface CancelFollowUp {
39
41
  question: string;
40
- /** The choices, in order; empty for a free text. */
42
+ /** The choices, in order; empty for a free text. What is recorded and what rules compare, whatever the language. */
41
43
  answers: string[];
44
+ /** 0.21.0: what each choice says in the visitor's language, parallel to `answers`; shown instead of them. */
45
+ answerLabels?: string[];
42
46
  }
43
47
  /**
44
48
  * 0.15.0: a different offer for some customers of one answer. Every condition that is set must hold; the first rule
@@ -86,7 +90,71 @@ export interface CancelFlowConfig {
86
90
  */
87
91
  offersFor: "business";
88
92
  }
89
- export type OnboardingStepKind = "tour" | "checklist" | "modal";
93
+ /** "question" (0.18.0): one question of a Questions item, a slide of its window. */
94
+ export type OnboardingStepKind = "tour" | "checklist" | "modal" | "question";
95
+ /**
96
+ * 0.18.0: what a checklist task opens. `page`: a path or address on the web, a deep link (`myapp://…`) or a screen name
97
+ * in an app, handed to the app's `onNavigate` when it passes one; `tour` / `modal`: another item of the config, after
98
+ * which the checklist comes back; `code`: the app's `onTask(taskId, item)`.
99
+ */
100
+ export type TaskOpens = {
101
+ kind: "page";
102
+ target: string;
103
+ } | {
104
+ kind: "tour";
105
+ id: string;
106
+ } | {
107
+ kind: "modal";
108
+ id: string;
109
+ } | {
110
+ kind: "code";
111
+ };
112
+ /**
113
+ * 0.18.0: a small picture beside a checklist task or above a modal's or the questions' heading: one of the SDK's own
114
+ * line icons (`FLOW_ICON_NAMES`, icons.ts), an emoji, or a picture (http(s)).
115
+ */
116
+ export type FlowIcon = {
117
+ kind: "builtin";
118
+ name: string;
119
+ } | {
120
+ kind: "emoji";
121
+ value: string;
122
+ } | {
123
+ kind: "image";
124
+ url: string;
125
+ };
126
+ /** 0.18.0: what plays when someone finishes a checklist, a tour or the questions. */
127
+ export type FinishAnimation = "none" | "confetti" | "fireworks" | "stars";
128
+ /**
129
+ * 0.18.0: one question of a Questions item: one choice of 2 to 6 options, or a short text. 0.21.0: a number scale, an
130
+ * "Other" with the person's own words, and a Skip button. An older app shows a scale as a text field, leaves "Other"
131
+ * out, and offers no Skip (its close button still ends the window).
132
+ */
133
+ export interface OnboardingQuestion {
134
+ /** The answer's name on the contact (`onboarding.<key>`) and in "People who answered …". */
135
+ key: string;
136
+ type: "choice" | "text" | "scale";
137
+ /** Choice: the options, in order; `id` is what is stored, `label` what people read. */
138
+ options?: {
139
+ id: string;
140
+ label: string;
141
+ }[];
142
+ /** Text: the field's hint. */
143
+ placeholder?: string;
144
+ /** 0.21.0, choice: one more option where people type their own words, stored as `other:<words>`. */
145
+ other?: boolean;
146
+ /** 0.21.0: the words of that option; "Other" when unset. */
147
+ otherLabel?: string;
148
+ /** 0.21.0, scale: the lowest and highest number, and the words under both ends. */
149
+ min?: number;
150
+ max?: number;
151
+ lowLabel?: string;
152
+ highLabel?: string;
153
+ /** 0.21.0: people may go on without answering. */
154
+ optional?: boolean;
155
+ /** 0.21.0: the words of that button; "Skip" when unset. */
156
+ skipLabel?: string;
157
+ }
90
158
  /** 0.17.0: where a tour bubble sits next to its element; "auto" (and no value) puts it below, else above, as before. */
91
159
  export type TourPlacement = "auto" | "top" | "bottom" | "left" | "right";
92
160
  /**
@@ -116,6 +184,12 @@ export interface OnboardingStep {
116
184
  url?: string;
117
185
  /** 0.17.0, checklist items: the id of a tour (another flow) the item starts; finishing the tour ticks the item. */
118
186
  startsTour?: string;
187
+ /** 0.18.0, checklist items: what the task opens (read before `startsTour`, which MRRocket still sends for a tour). */
188
+ opens?: TaskOpens;
189
+ /** 0.18.0, checklist items: the task's icon. */
190
+ icon?: FlowIcon;
191
+ /** 0.18.0, question steps: the question (the step's `title` is what people read). */
192
+ question?: OnboardingQuestion;
119
193
  }
120
194
  /** A pause in a flow (0.11.0): the next step shows this long after the one before was done. */
121
195
  export interface OnboardingWait {
@@ -148,10 +222,33 @@ export interface OnboardingFlow {
148
222
  * of the app ("/settings", "/projects/*"), or "From a checklist" (only a checklist task starts it).
149
223
  */
150
224
  trigger: string;
151
- /** 0.17.0: "signed_in" starts it on its own only for someone the app identified. */
152
- audience?: "signed_in";
225
+ /**
226
+ * 0.17.0: "signed_in" starts it on its own only for someone the app identified. 0.18.0: "answered" only for someone
227
+ * who gave `answered.option` to the question `answered.question` (its key).
228
+ */
229
+ audience?: "signed_in" | "answered";
230
+ /** 0.18.0: with `audience: "answered"`, the question's key and the option's id (or the typed text). */
231
+ answered?: {
232
+ question: string;
233
+ option: string;
234
+ };
153
235
  /** What every version shows: with `nodes`, only the in-app steps before the first wait or condition. */
154
236
  steps: OnboardingStep[];
237
+ /** 0.18.0: the icon above a modal's or the questions' heading. */
238
+ icon?: FlowIcon;
239
+ /** 0.18.0: what plays when the person finishes it (a checklist, a tour, the questions). */
240
+ finish?: FinishAnimation;
241
+ /**
242
+ * 0.18.0: "code": the app draws it itself (`useOnboarding(id)`, `mrrocket.onboarding.get(id)`); the SDK draws
243
+ * nothing for it, never starts it, and still records what the app reports. Such an item's `trigger` is
244
+ * "From your code" (older versions never start it).
245
+ */
246
+ shownBy?: "code";
247
+ /**
248
+ * 0.18.0: the item's real moment (read instead of `trigger`, see `momentOf`) when `trigger` is one older versions
249
+ * never start: "From your code", or `NEEDS_NEWER` for questions and items that follow another or ask for an answer.
250
+ */
251
+ when?: string;
155
252
  /** 0.11.0+: the whole flow with its waits and conditions. Read instead of `steps` when it is there. */
156
253
  nodes?: OnboardingNode[];
157
254
  }
@@ -183,6 +280,8 @@ export interface InAppState {
183
280
  messages: InAppMessage[];
184
281
  /** 0.11.0: the events the flows' conditions ask about that this person did (as `eventSlug`s). */
185
282
  events?: string[];
283
+ /** 0.18.0: the person's answers to onboarding questions, by the question's key (an option's id or the text). */
284
+ answers?: Record<string, string>;
186
285
  /**
187
286
  * 0.16.0: a live review request may ask this person now. The React Native client's `requestReview()` opens the
188
287
  * store's own rating dialog (expo-store-review) and reports `$review_prompt`; websites have no store dialog.
@@ -247,15 +346,22 @@ export type FlowView = {
247
346
  /** The step for the dots, 1 to `steps`. */
248
347
  step: number;
249
348
  steps: number;
250
- } | {
349
+ }
350
+ /** `answer` (0.18.0): a question's answer so far (an option's id or the typed text); `back`: an earlier question to go back to. */
351
+ | {
251
352
  type: "step";
252
353
  flow: OnboardingFlow;
253
354
  step: OnboardingStep;
254
355
  index: number;
255
356
  total: number;
256
357
  last: boolean;
358
+ answer?: string;
359
+ back?: boolean;
257
360
  }
258
- /** `tour`: the tour the item starts (0.17.0), when the config has it. */
361
+ /**
362
+ * `tour`: the tour the item starts (0.17.0), when the config has it. `opens` (0.18.0): what tapping the task opens
363
+ * (a tour or modal only when the config has it); `target` the item it opens.
364
+ */
259
365
  | {
260
366
  type: "checklist";
261
367
  flow: OnboardingFlow;
@@ -263,6 +369,8 @@ export type FlowView = {
263
369
  step: OnboardingStep;
264
370
  done: boolean;
265
371
  tour?: OnboardingFlow;
372
+ opens?: TaskOpens;
373
+ target?: OnboardingFlow;
266
374
  }[];
267
375
  } | {
268
376
  type: "message";
@@ -286,6 +394,13 @@ export interface FlowsEnv {
286
394
  auto?: boolean;
287
395
  /** The page the person is on (a path), for "Is on <page>?" conditions; without it they answer no. */
288
396
  path?: () => string | undefined;
397
+ /**
398
+ * 0.18.0: opens what a checklist task's "page or screen" names (a path, an address, a deep link, a screen name).
399
+ * The web and React Native clients pass the app's `onNavigate`, else their own default.
400
+ */
401
+ navigate?: (target: string) => void;
402
+ /** 0.18.0: a checklist task that runs the app's own code (`onTask(taskId, item)`). */
403
+ task?: (taskId: string, item: OnboardingFlow) => void;
289
404
  /** The clock, for tests. */
290
405
  now?: () => number;
291
406
  }
@@ -311,17 +426,56 @@ export interface FlowsController {
311
426
  confirm(comment?: string): void;
312
427
  close(): void;
313
428
  };
314
- /** `startTour(stepId)` (0.17.0): the tour a checklist item starts; the checklist comes back when it ends. */
429
+ /**
430
+ * `startTour(stepId)` (0.17.0): the tour a checklist item starts; the checklist comes back when it ends.
431
+ * 0.18.0: `open(stepId)` does what the task opens (a page, a tour, a modal, the app's code); `answer(value)` picks an
432
+ * option or types the text of the question on screen, `back()` returns to the question before. `item(id)` and the
433
+ * calls after it are for an item the app draws itself (`shownBy: "code"`).
434
+ */
315
435
  onboarding: {
316
436
  next(): void;
317
437
  check(stepId: string): void;
318
438
  dismiss(): void;
319
439
  startTour(stepId: string): boolean;
440
+ open(stepId: string): boolean;
441
+ answer(value: string): void;
442
+ /** 0.21.0: goes on from an optional question without an answer. */
443
+ skip(): void;
444
+ back(): void;
445
+ item(id: string): OnboardingItemState | null;
446
+ seen(id: string): void;
447
+ complete(id: string, stepId: string): void;
448
+ dismissItem(id: string): void;
449
+ answerItem(id: string, question: string, value: string): void;
320
450
  };
321
451
  message: {
322
452
  click(): void;
323
453
  dismiss(): void;
324
454
  };
455
+ /** 0.18.0: the animation to play now that someone finished an item (a new `key` each time), or null. */
456
+ finale(): {
457
+ kind: Exclude<FinishAnimation, "none">;
458
+ key: string;
459
+ } | null;
460
+ /** 0.18.0: the product's brand color from MRRocket, for the dialogs when the app passes no accent of its own. */
461
+ accent(): string | undefined;
462
+ /** 0.18.0: the person's answers to onboarding questions, by key. */
463
+ answers(): Record<string, string>;
464
+ }
465
+ /** 0.18.0: an item the app draws itself (`shownBy: "code"`), with the person's progress. */
466
+ export interface OnboardingItemState {
467
+ item: OnboardingFlow;
468
+ /** Its steps (a tour's steps, a checklist's tasks, the questions), each with whether the person did it. */
469
+ steps: (OnboardingStep & {
470
+ done: boolean;
471
+ answer?: string;
472
+ })[];
473
+ /** Every step is done. */
474
+ done: boolean;
475
+ /** The person closed it. */
476
+ dismissed: boolean;
477
+ /** Its moment has come for this person (the trigger MRRocket set, and who it is for); your code may ignore it. */
478
+ eligible: boolean;
325
479
  }
326
480
  /** The plain confirmation, when the product has no live cancel flow (or MRRocket was not reachable). */
327
481
  export declare const PLAIN_CANCEL: CancelFlowConfig;
@@ -335,6 +489,32 @@ export declare const startsOnLoad: (trigger: string) => boolean;
335
489
  export declare const FROM_CHECKLIST = "From a checklist";
336
490
  /** 0.17.0: a trigger that is a page of the app ("/settings", "/projects/*"): the flow starts when the person opens it. */
337
491
  export declare const isPageTrigger: (trigger: string) => boolean;
492
+ /** 0.18.0: the trigger of an item the app draws itself (`shownBy: "code"`); older versions never start it. */
493
+ export declare const FROM_CODE = "From your code";
494
+ /**
495
+ * 0.18.0: the trigger MRRocket sends for an item older versions could not show right (questions, "After <item> ends",
496
+ * "People who answered …"), so they never start it; its real moment is in `when`.
497
+ */
498
+ export declare const NEEDS_NEWER = "Needs tracking code 0.18.0";
499
+ /** An item's moment: `when` (0.18.0) where MRRocket sent one, else its trigger. */
500
+ export declare const momentOf: (f: Pick<OnboardingFlow, "trigger" | "when">) => string;
501
+ /** 0.18.0: the trigger "after:<item id>": the item starts once that item ended (finished or closed). */
502
+ export declare const AFTER_PREFIX = "after:";
503
+ /** The item an "after:<id>" trigger follows, or null. */
504
+ export declare const afterOf: (trigger: string | undefined) => string | null;
505
+ /** 0.18.0: what a task opens; a 0.17.0 `startsTour` reads as opening that tour. */
506
+ export declare const opensOf: (step: Pick<OnboardingStep, "opens" | "startsTour">) => TaskOpens | undefined;
507
+ /** 0.21.0: how a choice answer in the person's own words starts. */
508
+ export declare const OTHER_PREFIX = "other:";
509
+ /** 0.21.0: the numbers of a scale question, low to high. */
510
+ export declare const scaleOf: (q: OnboardingQuestion | undefined) => number[];
511
+ /**
512
+ * 0.18.0: a usable answer to a question: one of its options' ids, or a text of 1 to 500 characters. 0.21.0: the words
513
+ * of "Other", or a number of the scale.
514
+ */
515
+ export declare const answerOk: (q: OnboardingQuestion | undefined, value: string | undefined) => boolean;
516
+ /** The option's words for an answer (a text answer is its own words, "Other" the words typed, a number itself). */
517
+ export declare const answerLabel: (q: OnboardingQuestion | undefined, value: string) => string;
338
518
  /**
339
519
  * 0.17.0: how a video link plays. YouTube, Vimeo and Loom through their players without tracking cookies
340
520
  * (youtube-nocookie.com, Vimeo's `dnt=1`), a file (mp4, webm, mov, or an upload in MRRocket) in a plain video element;
@@ -353,7 +533,11 @@ export declare const discounted: (amount: number, percent: number) => number;
353
533
  /** "€20.30" in the customer's own currency, without a library. */
354
534
  export declare const money: (amount: number, currency: string) => string;
355
535
  /** The button of an offer. */
356
- export declare const offerButton: (o: CancelOffer) => "Send to the team" | "Pause instead" | "Switch plan" | "Accept offer";
536
+ export declare const offerButton: (o: CancelOffer) => string;
537
+ /** "3 months". */
538
+ export declare const monthsWord: (n: number) => string;
539
+ /** "for 3 months". */
540
+ export declare const forMonths: (n: number) => string;
357
541
  /** A link a message may open: http(s), or a path of the app. Nothing else (no `javascript:`). */
358
542
  export declare const safeUrl: (url: string | undefined) => string | undefined;
359
543
  /** The flow's nodes: the whole tree (0.11.0 config), or the plain steps of an older one. */