@mrrocket/sdk 0.18.0 → 0.22.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 +29 -0
- package/README.md +36 -1
- package/dist/api-client.d.ts +28 -4
- package/dist/api-client.js +30 -13
- package/dist/api-client.js.map +1 -1
- package/dist/browser/mrrocket-flows.js +8 -3
- package/dist/browser/mrrocket-messenger.js +38 -5
- package/dist/browser/mrrocket.js +1 -1
- package/dist/browser.d.ts +2 -2
- package/dist/browser.js +2 -1
- package/dist/browser.js.map +1 -1
- package/dist/client.d.ts +17 -1
- package/dist/client.js +25 -5
- package/dist/client.js.map +1 -1
- package/dist/core.d.ts +5 -1
- package/dist/core.js +1 -1
- package/dist/core.js.map +1 -1
- package/dist/feedback.js +161 -119
- package/dist/feedback.js.map +1 -1
- package/dist/flows-ui.d.ts +1 -1
- package/dist/flows-ui.js +100 -72
- package/dist/flows-ui.js.map +1 -1
- package/dist/flows-web.js +2 -1
- package/dist/flows-web.js.map +1 -1
- package/dist/flows.d.ts +38 -6
- package/dist/flows.js +51 -17
- package/dist/flows.js.map +1 -1
- package/dist/i18n.d.ts +22 -0
- package/dist/i18n.js +74 -0
- package/dist/i18n.js.map +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/messenger-ui.d.ts +9 -3
- package/dist/messenger-ui.js +324 -152
- package/dist/messenger-ui.js.map +1 -1
- package/dist/messenger.d.ts +3 -1
- package/dist/messenger.js +3 -2
- package/dist/messenger.js.map +1 -1
- package/dist/onboarding-report.d.ts +19 -0
- package/dist/onboarding-report.js +23 -0
- package/dist/onboarding-report.js.map +1 -0
- package/dist/onboarding-state.d.ts +3 -0
- package/dist/onboarding-state.js +7 -1
- package/dist/onboarding-state.js.map +1 -1
- package/dist/paywall.js +2 -1
- package/dist/paywall.js.map +1 -1
- package/dist/react-native/index.d.cts +93 -8
- package/dist/react-native/index.d.ts +93 -8
- package/dist/react-native/index.js +819 -511
- package/dist/react-native/index.js.map +1 -1
- package/dist/server.d.ts +4 -2
- package/dist/server.js +2 -2
- package/dist/server.js.map +1 -1
- package/dist/styles-css.d.ts +1 -1
- package/dist/styles-css.js +35 -2
- package/dist/styles-css.js.map +1 -1
- package/dist/survey.js +18 -14
- package/dist/survey.js.map +1 -1
- package/dist/ui.d.ts +2 -0
- package/dist/ui.js +15 -12
- package/dist/ui.js.map +1 -1
- package/package.json +6 -3
package/dist/flows.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// src/flows.ts
|
|
2
|
+
import { currentLocale, t, tf } from "./i18n.js";
|
|
2
3
|
var CANCEL_EVENT = "$cancel_flow";
|
|
3
4
|
var ONBOARDING_EVENT = "$onboarding";
|
|
4
5
|
var INAPP_EVENT = "$inapp";
|
|
@@ -8,18 +9,20 @@ var PLAIN_CANCEL = {
|
|
|
8
9
|
question: "",
|
|
9
10
|
reasons: [],
|
|
10
11
|
offers: {},
|
|
11
|
-
|
|
12
|
+
// Read when it is shown, so it follows the visitor's language.
|
|
13
|
+
get confirm() {
|
|
14
|
+
return { title: t("Cancel your subscription?"), body: t("You keep access until the end of the billing period."), button: t("Cancel subscription") };
|
|
15
|
+
},
|
|
12
16
|
offersFor: "business"
|
|
13
17
|
};
|
|
14
|
-
var FAILED = "Something went wrong. Please try again.";
|
|
15
18
|
var PROGRESS_KEY = "mrrocket:onboarding";
|
|
16
19
|
var eventSlug = (s) => s.trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
17
20
|
var SIGNUP = /* @__PURE__ */ new Set(["signed_up", "signup", "sign_up", "registered", "account_created", "user_signed_up"]);
|
|
18
21
|
var matchesTrigger = (trigger, event) => {
|
|
19
|
-
const
|
|
22
|
+
const t2 = eventSlug(trigger);
|
|
20
23
|
const e = eventSlug(event);
|
|
21
|
-
if (!
|
|
22
|
-
return
|
|
24
|
+
if (!t2 || !e) return false;
|
|
25
|
+
return t2 === e || SIGNUP.has(t2) && SIGNUP.has(e);
|
|
23
26
|
};
|
|
24
27
|
var startsOnLoad = (trigger) => /^(first (launch|visit|open|session|login|sign ?in|app open)|app (opened|launched)|on load|every visit|always)?$/i.test(trigger.trim());
|
|
25
28
|
var FROM_CHECKLIST = "From a checklist";
|
|
@@ -30,16 +33,30 @@ var momentOf = (f) => f.when ?? f.trigger;
|
|
|
30
33
|
var manual = (trigger) => eventSlug(trigger) === "from_a_checklist" || eventSlug(trigger) === "from_your_code" || eventSlug(trigger) === eventSlug(NEEDS_NEWER);
|
|
31
34
|
var AFTER_PREFIX = "after:";
|
|
32
35
|
var afterOf = (trigger) => {
|
|
33
|
-
const
|
|
34
|
-
return
|
|
36
|
+
const t2 = (trigger ?? "").trim();
|
|
37
|
+
return t2.toLowerCase().startsWith(AFTER_PREFIX) ? t2.slice(AFTER_PREFIX.length).trim() || null : null;
|
|
35
38
|
};
|
|
36
39
|
var opensOf = (step) => step.opens ?? (step.startsTour ? { kind: "tour", id: step.startsTour } : void 0);
|
|
40
|
+
var OTHER_PREFIX = "other:";
|
|
41
|
+
var scaleOf = (q) => {
|
|
42
|
+
const min = q?.min ?? 0;
|
|
43
|
+
const max = q?.max ?? 10;
|
|
44
|
+
return Array.from({ length: Math.max(0, Math.min(max - min, 20) + 1) }, (_, i) => min + i);
|
|
45
|
+
};
|
|
37
46
|
var answerOk = (q, value) => {
|
|
38
47
|
if (!q || value == null) return false;
|
|
39
|
-
if (q.type === "choice")
|
|
48
|
+
if (q.type === "choice") {
|
|
49
|
+
if (q.other && value.startsWith(OTHER_PREFIX)) return value.slice(OTHER_PREFIX.length).trim().length > 0;
|
|
50
|
+
return (q.options ?? []).some((o) => o.id === value);
|
|
51
|
+
}
|
|
52
|
+
if (q.type === "scale") return scaleOf(q).some((n) => String(n) === value);
|
|
40
53
|
return value.trim().length > 0 && value.length <= 500;
|
|
41
54
|
};
|
|
42
|
-
var answerLabel = (q, value) =>
|
|
55
|
+
var answerLabel = (q, value) => {
|
|
56
|
+
if (q?.type !== "choice") return value.trim();
|
|
57
|
+
if (q.other && value.startsWith(OTHER_PREFIX)) return value.slice(OTHER_PREFIX.length).trim();
|
|
58
|
+
return q.options?.find((o) => o.id === value)?.label ?? value;
|
|
59
|
+
};
|
|
43
60
|
var videoEmbed = (url) => {
|
|
44
61
|
const u = (url ?? "").trim();
|
|
45
62
|
if (!/^https?:\/\//i.test(u)) return null;
|
|
@@ -61,12 +78,14 @@ var runId = () => `cf_${Math.random().toString(36).slice(2, 10)}${Date.now().toS
|
|
|
61
78
|
var discounted = (amount, percent) => Math.round(amount * (1 - percent / 100) * 100) / 100;
|
|
62
79
|
var money = (amount, currency) => {
|
|
63
80
|
try {
|
|
64
|
-
return new Intl.NumberFormat(
|
|
81
|
+
return new Intl.NumberFormat(currentLocale(), { style: "currency", currency }).format(amount);
|
|
65
82
|
} catch {
|
|
66
83
|
return `${amount.toFixed(2)} ${currency}`;
|
|
67
84
|
}
|
|
68
85
|
};
|
|
69
|
-
var offerButton = (o) => o.kind === "contact" ? "Send to the team" : o.kind === "pause" ? "Pause instead" : o.kind === "downgrade" ? "Switch plan" : "Accept offer";
|
|
86
|
+
var offerButton = (o) => o.kind === "contact" ? t("Send to the team") : o.kind === "pause" ? t("Pause instead") : o.kind === "downgrade" ? t("Switch plan") : t("Accept offer");
|
|
87
|
+
var monthsWord = (n) => n === 1 ? t("1 month") : tf("{n} months", { n });
|
|
88
|
+
var forMonths = (n) => tf("for {months}", { months: monthsWord(n) });
|
|
70
89
|
var safeUrl = (url) => {
|
|
71
90
|
const u = (url ?? "").trim();
|
|
72
91
|
return /^https?:\/\//i.test(u) || /^\/(?!\/)/.test(u) ? u : void 0;
|
|
@@ -261,8 +280,8 @@ var createFlows = (env) => {
|
|
|
261
280
|
flow,
|
|
262
281
|
items: items.map((s) => {
|
|
263
282
|
const o = opensOf(s);
|
|
264
|
-
const
|
|
265
|
-
const target =
|
|
283
|
+
const t2 = o && (o.kind === "tour" || o.kind === "modal") && o.id !== flow.id ? flowById(o.id) : void 0;
|
|
284
|
+
const target = t2 && t2.shownBy !== "code" && nodesOf(t2).length ? t2 : void 0;
|
|
266
285
|
const opens = o && (o.kind === "page" ? !!o.target.trim() : o.kind === "code" || !!target) ? o : void 0;
|
|
267
286
|
return {
|
|
268
287
|
step: s,
|
|
@@ -401,7 +420,7 @@ var createFlows = (env) => {
|
|
|
401
420
|
};
|
|
402
421
|
const answerStep = (flow, step, raw) => {
|
|
403
422
|
const q = step.question;
|
|
404
|
-
const value = q.type === "text" ? raw.trim().slice(0, 500) : raw;
|
|
423
|
+
const value = q.type === "text" ? raw.trim().slice(0, 500) : raw.startsWith(OTHER_PREFIX) ? OTHER_PREFIX + raw.slice(OTHER_PREFIX.length).trim().slice(0, 490) : raw;
|
|
405
424
|
answers.set(q.key, value);
|
|
406
425
|
drafts.delete(step.id);
|
|
407
426
|
markDone(prog(flow.id), step.id);
|
|
@@ -512,7 +531,7 @@ var createFlows = (env) => {
|
|
|
512
531
|
() => finish(c, r),
|
|
513
532
|
() => {
|
|
514
533
|
c.busy = false;
|
|
515
|
-
c.error =
|
|
534
|
+
c.error = t("Something went wrong. Please try again.");
|
|
516
535
|
emit();
|
|
517
536
|
}
|
|
518
537
|
);
|
|
@@ -592,8 +611,8 @@ var createFlows = (env) => {
|
|
|
592
611
|
answer: (text) => {
|
|
593
612
|
const c = cancel;
|
|
594
613
|
if (!c || c.busy || c.screen !== "followup") return;
|
|
595
|
-
const
|
|
596
|
-
c.answer =
|
|
614
|
+
const t2 = text.slice(0, 500);
|
|
615
|
+
c.answer = t2.trim() ? t2 : void 0;
|
|
597
616
|
emit();
|
|
598
617
|
},
|
|
599
618
|
next: () => {
|
|
@@ -735,6 +754,17 @@ var createFlows = (env) => {
|
|
|
735
754
|
drafts.set(v.step.id, String(value).slice(0, 500));
|
|
736
755
|
emit();
|
|
737
756
|
},
|
|
757
|
+
skip: () => {
|
|
758
|
+
const v = onboardingView();
|
|
759
|
+
const q = v?.type === "step" && v.step.kind === "question" ? v.step.question : void 0;
|
|
760
|
+
if (v?.type !== "step" || !q?.optional) return;
|
|
761
|
+
drafts.delete(v.step.id);
|
|
762
|
+
markDone(prog(v.flow.id), v.step.id);
|
|
763
|
+
env.track(ONBOARDING_EVENT, { flow: v.flow.id, step: v.step.id, kind: "question", action: "completed", question: q.key, skipped: true });
|
|
764
|
+
celebrate(v.flow);
|
|
765
|
+
save();
|
|
766
|
+
emit();
|
|
767
|
+
},
|
|
738
768
|
back: () => {
|
|
739
769
|
const v = onboardingView();
|
|
740
770
|
if (v?.type !== "step" || v.step.kind !== "question" || !v.back) return;
|
|
@@ -837,6 +867,7 @@ export {
|
|
|
837
867
|
INAPP_EVENT,
|
|
838
868
|
NEEDS_NEWER,
|
|
839
869
|
ONBOARDING_EVENT,
|
|
870
|
+
OTHER_PREFIX,
|
|
840
871
|
PLAIN_CANCEL,
|
|
841
872
|
REVIEW_EVENT,
|
|
842
873
|
afterOf,
|
|
@@ -845,12 +876,14 @@ export {
|
|
|
845
876
|
createFlows,
|
|
846
877
|
discounted,
|
|
847
878
|
eventSlug,
|
|
879
|
+
forMonths,
|
|
848
880
|
isPageTrigger,
|
|
849
881
|
matchesTrigger,
|
|
850
882
|
mediaOf,
|
|
851
883
|
momentOf,
|
|
852
884
|
money,
|
|
853
885
|
monthsSince,
|
|
886
|
+
monthsWord,
|
|
854
887
|
nodesOf,
|
|
855
888
|
offerButton,
|
|
856
889
|
opensOf,
|
|
@@ -858,6 +891,7 @@ export {
|
|
|
858
891
|
ruleMatches,
|
|
859
892
|
runId,
|
|
860
893
|
safeUrl,
|
|
894
|
+
scaleOf,
|
|
861
895
|
startsOnLoad,
|
|
862
896
|
videoEmbed,
|
|
863
897
|
waitMs
|