@mrrocket/sdk 0.15.0 → 0.16.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 +10 -0
- package/README.md +36 -1
- package/dist/api-client.d.ts +5 -4
- package/dist/api-client.js +12 -8
- package/dist/api-client.js.map +1 -1
- package/dist/api.d.ts +4 -1
- package/dist/api.js +2 -1
- package/dist/api.js.map +1 -1
- package/dist/batch.d.ts +6 -4
- package/dist/batch.js +3 -3
- package/dist/batch.js.map +1 -1
- package/dist/browser/mrrocket-flows.js +2 -2
- package/dist/browser/mrrocket-forms.js +1 -1
- package/dist/browser/mrrocket-messenger.js +2 -2
- package/dist/browser/mrrocket-push.js +1 -1
- package/dist/browser/mrrocket-replay.js +3 -3
- package/dist/browser/mrrocket.js +1 -1
- package/dist/client.d.ts +10 -2
- package/dist/client.js +36 -15
- package/dist/client.js.map +1 -1
- package/dist/context.d.ts +5 -1
- package/dist/context.js.map +1 -1
- package/dist/core.d.ts +1 -1
- package/dist/core.js +1 -1
- package/dist/core.js.map +1 -1
- package/dist/errors.d.ts +5 -1
- package/dist/errors.js +8 -2
- package/dist/errors.js.map +1 -1
- package/dist/flows-web.d.ts +2 -0
- package/dist/flows-web.js +4 -1
- package/dist/flows-web.js.map +1 -1
- package/dist/flows.d.ts +10 -0
- package/dist/flows.js +2 -0
- package/dist/flows.js.map +1 -1
- package/dist/forms.d.ts +4 -0
- package/dist/forms.js +4 -1
- package/dist/forms.js.map +1 -1
- package/dist/identity.d.ts +42 -0
- package/dist/identity.js +24 -0
- package/dist/identity.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js.map +1 -1
- package/dist/messenger-ui.d.ts +2 -0
- package/dist/messenger-ui.js +2 -2
- package/dist/messenger-ui.js.map +1 -1
- package/dist/messenger.js +3 -2
- package/dist/messenger.js.map +1 -1
- package/dist/push-web.d.ts +2 -13
- package/dist/push-web.js +4 -2
- package/dist/push-web.js.map +1 -1
- package/dist/react-native/index.d.cts +61 -9
- package/dist/react-native/index.d.ts +61 -9
- package/dist/react-native/index.js +107 -28
- package/dist/react-native/index.js.map +1 -1
- package/dist/replay.d.ts +4 -1
- package/dist/replay.js +8 -2
- package/dist/replay.js.map +1 -1
- package/dist/server.d.ts +2 -0
- package/dist/server.js +2 -0
- package/dist/server.js.map +1 -1
- package/dist/user-hash.d.ts +27 -0
- package/dist/user-hash.js +24 -0
- package/dist/user-hash.js.map +1 -0
- package/package.json +5 -1
|
@@ -43,6 +43,7 @@ __export(native_exports, {
|
|
|
43
43
|
useOnboarding: () => useOnboarding,
|
|
44
44
|
usePaywall: () => usePaywall,
|
|
45
45
|
usePush: () => usePush,
|
|
46
|
+
useReview: () => useReview,
|
|
46
47
|
useText: () => useText,
|
|
47
48
|
useVariant: () => useVariant
|
|
48
49
|
});
|
|
@@ -50,7 +51,7 @@ module.exports = __toCommonJS(native_exports);
|
|
|
50
51
|
var import_react3 = require("react");
|
|
51
52
|
|
|
52
53
|
// src/core.ts
|
|
53
|
-
var SDK_VERSION = "0.
|
|
54
|
+
var SDK_VERSION = "0.16.0";
|
|
54
55
|
var propOf = (person, name) => {
|
|
55
56
|
const want = name.trim().toLowerCase();
|
|
56
57
|
for (const [k, v] of Object.entries(person)) if (k.toLowerCase() === want) return v;
|
|
@@ -172,6 +173,23 @@ var textChanges = (config, distinctId, preview) => {
|
|
|
172
173
|
};
|
|
173
174
|
var newDistinctId = () => typeof crypto !== "undefined" && "randomUUID" in crypto ? crypto.randomUUID() : `ck_${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`;
|
|
174
175
|
|
|
176
|
+
// src/identity.ts
|
|
177
|
+
var UNSIGNED_HELP = "401: sign the user id on your server with userHash(id) from @mrrocket/sdk/next/server and pass identify(id, props, { hash }).";
|
|
178
|
+
var warnUnsigned = (status, log = (m) => console.warn(m)) => {
|
|
179
|
+
const g = globalThis;
|
|
180
|
+
if (status !== 401 || g.__mrrocketUnsigned) return;
|
|
181
|
+
g.__mrrocketUnsigned = true;
|
|
182
|
+
log(`[MRRocket] ${UNSIGNED_HELP}`);
|
|
183
|
+
};
|
|
184
|
+
var nextSigned = (signed, id, hash, log = (m) => console.warn(m)) => {
|
|
185
|
+
const h3 = typeof hash === "string" ? hash.trim().toLowerCase() : "";
|
|
186
|
+
if (/^[0-9a-f]{64}$/.test(h3)) return { id, hash: h3 };
|
|
187
|
+
if (h3) log("[MRRocket] identify: that hash is no userHash(id); not sent.");
|
|
188
|
+
return signed && signed.id === id ? signed : null;
|
|
189
|
+
};
|
|
190
|
+
var hashFor = (signed, id) => signed && id && signed.id === id ? signed.hash : void 0;
|
|
191
|
+
var hashForAll = (signed, ids) => signed && ids.some((id) => id === signed.id) && ids.every((id) => !id || id === signed.id) ? signed.hash : void 0;
|
|
192
|
+
|
|
175
193
|
// src/api-client.ts
|
|
176
194
|
var CHAT_FILE_MAX_BYTES = 10 * 1024 * 1024;
|
|
177
195
|
var CHAT_FILES_PER_MESSAGE = 4;
|
|
@@ -212,6 +230,7 @@ var call = async (url, init, signal) => {
|
|
|
212
230
|
throw new ApiError("Could not reach the server. Check your connection and try again.", 0);
|
|
213
231
|
}
|
|
214
232
|
if (!res.ok) {
|
|
233
|
+
warnUnsigned(res.status);
|
|
215
234
|
let detail = "";
|
|
216
235
|
try {
|
|
217
236
|
detail = (await res.json()).error ?? "";
|
|
@@ -223,21 +242,22 @@ var call = async (url, init, signal) => {
|
|
|
223
242
|
};
|
|
224
243
|
var createApi = (c) => {
|
|
225
244
|
const base = `${c.host}/api/sdk`;
|
|
226
|
-
const who = { key: c.apiKey, distinctId: c.distinctId, user: c.user };
|
|
245
|
+
const who = { key: c.apiKey, distinctId: c.distinctId, user: c.user, userHash: c.userHash };
|
|
246
|
+
const me = { key: c.apiKey, distinctId: c.distinctId, userHash: c.userHash };
|
|
227
247
|
const post = (path, body, signal) => call(`${base}${path}`, { method: "POST", body: JSON.stringify({ ...who, ...body }) }, signal);
|
|
228
248
|
return {
|
|
229
|
-
list: (o, signal) => call(`${base}/feedback?${qs({
|
|
230
|
-
post: (id, signal) => call(`${base}/feedback/${encodeURIComponent(id)}?${qs(
|
|
231
|
-
roadmap: (signal) => call(`${base}/feedback/roadmap?${qs(
|
|
249
|
+
list: (o, signal) => call(`${base}/feedback?${qs({ ...me, board: o.board, sort: o.sort, q: o.q })}`, void 0, signal),
|
|
250
|
+
post: (id, signal) => call(`${base}/feedback/${encodeURIComponent(id)}?${qs(me)}`, void 0, signal),
|
|
251
|
+
roadmap: (signal) => call(`${base}/feedback/roadmap?${qs(me)}`, void 0, signal),
|
|
232
252
|
changelog: (signal) => call(`${base}/feedback/changelog?${qs({ key: c.apiKey })}`, void 0, signal),
|
|
233
253
|
submit: (p) => post("/feedback", p),
|
|
234
254
|
vote: (id) => post(`/feedback/${encodeURIComponent(id)}/vote`, {}),
|
|
235
255
|
comments: (id, signal) => call(`${base}/feedback/${encodeURIComponent(id)}/comments?${qs({ key: c.apiKey })}`, void 0, signal),
|
|
236
256
|
comment: (id, body) => post(`/feedback/${encodeURIComponent(id)}/comments`, { body }),
|
|
237
|
-
survey: (url, signal) => call(`${base}/surveys?${qs({
|
|
257
|
+
survey: (url, signal) => call(`${base}/surveys?${qs({ ...me, url })}`, void 0, signal),
|
|
238
258
|
seen: (id) => post(`/surveys/${encodeURIComponent(id)}/seen`, { user: void 0 }),
|
|
239
259
|
respond: (id, r) => post(`/surveys/${encodeURIComponent(id)}/respond`, r),
|
|
240
|
-
chat: (signal) => call(`${base}/messages?${qs(
|
|
260
|
+
chat: (signal) => call(`${base}/messages?${qs(me)}`, void 0, signal),
|
|
241
261
|
/** A message; `attachments` are upload ids from `uploadChatFile` (then the body may be empty). */
|
|
242
262
|
sendChat: (m) => post("/messages", m),
|
|
243
263
|
/** Uploads one picked file for the next message (pictures and PDFs, at most 10 MB); answers its upload id. */
|
|
@@ -245,14 +265,15 @@ var createApi = (c) => {
|
|
|
245
265
|
const form = new FormData();
|
|
246
266
|
form.append("key", c.apiKey);
|
|
247
267
|
form.append("distinctId", c.distinctId);
|
|
268
|
+
if (c.userHash) form.append("userHash", c.userHash);
|
|
248
269
|
if ("uri" in file) form.append("file", file);
|
|
249
270
|
else form.append("file", file, file.name || "file");
|
|
250
271
|
return call(`${base}/messages/attachments`, { method: "POST", body: form }, signal);
|
|
251
272
|
},
|
|
252
273
|
/** Where a sent file of this visitor's chat is read (an image's src, a PDF's link). */
|
|
253
|
-
attachmentUrl: (id) => `${base}/messages/attachments/${encodeURIComponent(id)}?${qs(
|
|
274
|
+
attachmentUrl: (id) => `${base}/messages/attachments/${encodeURIComponent(id)}?${qs(me)}`,
|
|
254
275
|
articles: (q, signal) => call(`${base}/articles?${qs({ key: c.apiKey, q })}`, void 0, signal),
|
|
255
|
-
article: (id, signal) => call(`${base}/articles/${encodeURIComponent(id)}?${qs(
|
|
276
|
+
article: (id, signal) => call(`${base}/articles/${encodeURIComponent(id)}?${qs(me)}`, void 0, signal),
|
|
256
277
|
messengerLook: (signal) => call(`${base}/messenger?${qs({ key: c.apiKey })}`, void 0, signal),
|
|
257
278
|
rateArticle: (id, helpful) => post(`/articles/${encodeURIComponent(id)}/rate`, { helpful })
|
|
258
279
|
};
|
|
@@ -274,8 +295,8 @@ var byteLength = (s) => {
|
|
|
274
295
|
}
|
|
275
296
|
return n;
|
|
276
297
|
};
|
|
277
|
-
var batchRequests = (key, events, sdk) => {
|
|
278
|
-
const head = `{"key":${JSON.stringify(key)}
|
|
298
|
+
var batchRequests = (key, events, sdk, userHash) => {
|
|
299
|
+
const head = `{"key":${JSON.stringify(key)},${userHash ? `"userHash":${JSON.stringify(userHash)},` : ""}"sdk":${JSON.stringify(sdk)},"events":[`;
|
|
279
300
|
const empty = byteLength(head) + 2;
|
|
280
301
|
const out = [];
|
|
281
302
|
let chunk = [];
|
|
@@ -317,6 +338,7 @@ var describeError = (error) => {
|
|
|
317
338
|
var CANCEL_EVENT = "$cancel_flow";
|
|
318
339
|
var ONBOARDING_EVENT = "$onboarding";
|
|
319
340
|
var INAPP_EVENT = "$inapp";
|
|
341
|
+
var REVIEW_EVENT = "$review_prompt";
|
|
320
342
|
var PLAIN_CANCEL = {
|
|
321
343
|
version: 0,
|
|
322
344
|
question: "",
|
|
@@ -1047,7 +1069,7 @@ var createRecorder = (deps, st) => {
|
|
|
1047
1069
|
const batch = frames.splice(0, frames.length);
|
|
1048
1070
|
const ms = marks.splice(0, marks.length);
|
|
1049
1071
|
const size = deps.screen();
|
|
1050
|
-
const { distinctId, identified } = st.who();
|
|
1072
|
+
const { distinctId, identified, userHash } = st.who();
|
|
1051
1073
|
const body = JSON.stringify({
|
|
1052
1074
|
key: st.apiKey,
|
|
1053
1075
|
consent: { replay: true },
|
|
@@ -1059,11 +1081,12 @@ var createRecorder = (deps, st) => {
|
|
|
1059
1081
|
meta: { first: batch[0].t, last: batch[batch.length - 1].t, vw: size ? Math.round(size.w) : null, vh: size ? Math.round(size.h) : null, marks: ms },
|
|
1060
1082
|
distinctId,
|
|
1061
1083
|
identified,
|
|
1084
|
+
...userHash ? { userHash } : {},
|
|
1062
1085
|
trigger: r.trigger,
|
|
1063
1086
|
app: st.app
|
|
1064
1087
|
});
|
|
1065
1088
|
const status = await deps.send(body);
|
|
1066
|
-
if (status === 403 || status === 409 || status === 413) r.stopped = true;
|
|
1089
|
+
if (status === 401 || status === 403 || status === 409 || status === 413) r.stopped = true;
|
|
1067
1090
|
};
|
|
1068
1091
|
const tick = async () => {
|
|
1069
1092
|
if (busy || !st.allowed() || !st.config()) return;
|
|
@@ -1223,6 +1246,7 @@ var createClient = (options, deps) => {
|
|
|
1223
1246
|
let installId = null;
|
|
1224
1247
|
let memoryId = newDistinctId();
|
|
1225
1248
|
let identified;
|
|
1249
|
+
let signed = null;
|
|
1226
1250
|
let person;
|
|
1227
1251
|
let config = null;
|
|
1228
1252
|
let queue = [];
|
|
@@ -1257,6 +1281,13 @@ var createClient = (options, deps) => {
|
|
|
1257
1281
|
const errorQueue = [];
|
|
1258
1282
|
const errorsSeen = /* @__PURE__ */ new Set();
|
|
1259
1283
|
let errorsSent = 0;
|
|
1284
|
+
const fetchInApp = async (id) => {
|
|
1285
|
+
if (!apiKey) return null;
|
|
1286
|
+
const hash = hashOf(id);
|
|
1287
|
+
const r = await deps.fetch(`${host}/api/sdk/inapp?key=${encodeURIComponent(apiKey)}&distinctId=${encodeURIComponent(id)}${hash ? `&userHash=${hash}` : ""}`, { method: "GET" });
|
|
1288
|
+
warnUnsigned(r.status, deps.log);
|
|
1289
|
+
return r.ok ? await r.json() : null;
|
|
1290
|
+
};
|
|
1260
1291
|
const paywall = createPaywallHost({ config: () => config, distinctId: () => distinctId(), track: (event, props) => record(event, props) });
|
|
1261
1292
|
const flows = createFlows({
|
|
1262
1293
|
track: (event, props) => record(event, props),
|
|
@@ -1267,11 +1298,7 @@ var createClient = (options, deps) => {
|
|
|
1267
1298
|
set: (k, v) => void set(k, v)
|
|
1268
1299
|
} : null,
|
|
1269
1300
|
openUrl: deps.openUrl,
|
|
1270
|
-
fetchInApp:
|
|
1271
|
-
if (!apiKey) return null;
|
|
1272
|
-
const r = await deps.fetch(`${host}/api/sdk/inapp?key=${encodeURIComponent(apiKey)}&distinctId=${encodeURIComponent(id)}`, { method: "GET" });
|
|
1273
|
-
return r.ok ? await r.json() : null;
|
|
1274
|
-
}
|
|
1301
|
+
fetchInApp: (id) => fetchInApp(id)
|
|
1275
1302
|
});
|
|
1276
1303
|
const refreshFlows = () => {
|
|
1277
1304
|
if (!isReady || closed) return;
|
|
@@ -1334,6 +1361,7 @@ var createClient = (options, deps) => {
|
|
|
1334
1361
|
};
|
|
1335
1362
|
const distinctId = () => identified ?? (consent === "persistent" && installId ? installId : memoryId);
|
|
1336
1363
|
const sendId = () => consent === "persistent" ? distinctId() : identified;
|
|
1364
|
+
const hashOf = (id) => hashFor(signed, id);
|
|
1337
1365
|
const touchSession = () => {
|
|
1338
1366
|
const t = now();
|
|
1339
1367
|
if (!session || t - session.last >= SESSION_TIMEOUT_MS) session = { id: newDistinctId(), last: t };
|
|
@@ -1371,6 +1399,7 @@ var createClient = (options, deps) => {
|
|
|
1371
1399
|
const timer = ctl ? setTimeoutFn(() => ctl.abort(), REQUEST_TIMEOUT_MS) : null;
|
|
1372
1400
|
try {
|
|
1373
1401
|
const r = await deps.fetch(`${host}${path}`, { method: "POST", headers: { "content-type": "application/json" }, body, signal: ctl?.signal });
|
|
1402
|
+
warnUnsigned(r.status, deps.log);
|
|
1374
1403
|
return r.status;
|
|
1375
1404
|
} catch {
|
|
1376
1405
|
return 0;
|
|
@@ -1382,7 +1411,7 @@ var createClient = (options, deps) => {
|
|
|
1382
1411
|
if (!queue.length || consent === "off" || !apiKey) return;
|
|
1383
1412
|
if (now() < backoffUntil) return;
|
|
1384
1413
|
const snapshot = queue.slice();
|
|
1385
|
-
const requests = batchRequests(apiKey, snapshot, sdk);
|
|
1414
|
+
const requests = batchRequests(apiKey, snapshot, sdk, hashOf(sendId()));
|
|
1386
1415
|
const included = new Set(requests.flatMap((r) => r.events));
|
|
1387
1416
|
const done = /* @__PURE__ */ new Set();
|
|
1388
1417
|
for (const r of requests) {
|
|
@@ -1393,7 +1422,7 @@ var createClient = (options, deps) => {
|
|
|
1393
1422
|
backoffUntil = 0;
|
|
1394
1423
|
} else if (status >= 400 && status < 500 && status !== 408 && status !== 429) {
|
|
1395
1424
|
r.events.forEach((e) => done.add(e));
|
|
1396
|
-
warn(`Events were rejected with ${status}. Check the public key (MRRocket \u203A Settings \u203A Products) and the host.`);
|
|
1425
|
+
if (status !== 401) warn(`Events were rejected with ${status}. Check the public key (MRRocket \u203A Settings \u203A Products) and the host.`);
|
|
1397
1426
|
} else {
|
|
1398
1427
|
failures++;
|
|
1399
1428
|
backoffUntil = now() + Math.min(MAX_BACKOFF_MS, 1e3 * 2 ** failures);
|
|
@@ -1432,8 +1461,9 @@ var createClient = (options, deps) => {
|
|
|
1432
1461
|
}
|
|
1433
1462
|
while (errorQueue.length) {
|
|
1434
1463
|
const batch = errorQueue.splice(0, 4);
|
|
1435
|
-
const
|
|
1436
|
-
|
|
1464
|
+
const userHash = hashForAll(signed, batch.map((r) => r.distinctId));
|
|
1465
|
+
const status = await post("/api/sdk/errors", JSON.stringify({ key: apiKey, ...userHash ? { userHash } : {}, sdk, errors: batch }));
|
|
1466
|
+
if (status >= 400 && status < 500 && status !== 429 && status !== 401) warn(`Error reports were rejected with ${status}. Check the public key and the host.`);
|
|
1437
1467
|
}
|
|
1438
1468
|
};
|
|
1439
1469
|
const capture = (error, mechanism, fatal = false) => {
|
|
@@ -1491,7 +1521,7 @@ var createClient = (options, deps) => {
|
|
|
1491
1521
|
allowed: () => replayOn && loaded && !closed && consent !== "off" && !!apiKey,
|
|
1492
1522
|
config: () => config?.replay,
|
|
1493
1523
|
session: () => session?.id ?? touchSession(),
|
|
1494
|
-
who: () => ({ distinctId: sendId(), identified: !!identified }),
|
|
1524
|
+
who: () => ({ distinctId: sendId(), identified: !!identified, userHash: hashOf(sendId()) }),
|
|
1495
1525
|
apiKey,
|
|
1496
1526
|
app: context
|
|
1497
1527
|
}
|
|
@@ -1541,6 +1571,7 @@ var createClient = (options, deps) => {
|
|
|
1541
1571
|
};
|
|
1542
1572
|
let pushToken = null;
|
|
1543
1573
|
let pushFor;
|
|
1574
|
+
let pushHash;
|
|
1544
1575
|
let pushOff = null;
|
|
1545
1576
|
const opened = /* @__PURE__ */ new Set();
|
|
1546
1577
|
const onPushOpen = (data) => {
|
|
@@ -1568,18 +1599,20 @@ var createClient = (options, deps) => {
|
|
|
1568
1599
|
if (!apiKey || consent === "off") return { status: "error", reason: !apiKey ? "No public key." : "The consent is off." };
|
|
1569
1600
|
if (!identified) return { status: "not-signed-in" };
|
|
1570
1601
|
const who = identified;
|
|
1602
|
+
const userHash = hashOf(who);
|
|
1571
1603
|
try {
|
|
1572
1604
|
const permission = await deps.push.permission(o.ask !== false);
|
|
1573
1605
|
if (permission !== "granted") return { status: permission === "denied" ? "denied" : "not-asked" };
|
|
1574
1606
|
const token = await deps.push.token(o.projectId);
|
|
1575
1607
|
if (!token) return { status: "unavailable", reason: "This device has no push token (a simulator, or no EAS project id)." };
|
|
1576
|
-
const status = await post("/api/sdk/push", JSON.stringify({ key: apiKey, distinctId: who, platform: "expo", token, app: context }));
|
|
1608
|
+
const status = await post("/api/sdk/push", JSON.stringify({ key: apiKey, distinctId: who, userHash, platform: "expo", token, app: context }));
|
|
1577
1609
|
if (status < 200 || status >= 300) {
|
|
1578
1610
|
warn(`Push registration was rejected with ${status || "no answer"}. Check the public key and the host.`);
|
|
1579
1611
|
return { status: "error", reason: `MRRocket answered ${status || "nothing"}.` };
|
|
1580
1612
|
}
|
|
1581
1613
|
pushToken = token;
|
|
1582
1614
|
pushFor = who;
|
|
1615
|
+
pushHash = userHash;
|
|
1583
1616
|
listenForOpens();
|
|
1584
1617
|
debug("Registered for push.");
|
|
1585
1618
|
return { status: "registered", token };
|
|
@@ -1591,9 +1624,28 @@ var createClient = (options, deps) => {
|
|
|
1591
1624
|
const token = pushToken;
|
|
1592
1625
|
if (!token || !apiKey) return false;
|
|
1593
1626
|
pushToken = null;
|
|
1594
|
-
const status = await post("/api/sdk/push", JSON.stringify({ key: apiKey, distinctId: pushFor, platform: "expo", token, remove: true }));
|
|
1627
|
+
const status = await post("/api/sdk/push", JSON.stringify({ key: apiKey, distinctId: pushFor, userHash: pushHash, platform: "expo", token, remove: true }));
|
|
1595
1628
|
return status >= 200 && status < 300;
|
|
1596
1629
|
};
|
|
1630
|
+
let reviewing = false;
|
|
1631
|
+
const requestReview = async () => {
|
|
1632
|
+
if (!deps.storeReview) return "unavailable";
|
|
1633
|
+
await loadedNow();
|
|
1634
|
+
if (!apiKey || consent === "off") return "not-now";
|
|
1635
|
+
if (!identified) return "not-signed-in";
|
|
1636
|
+
if (reviewing) return "not-now";
|
|
1637
|
+
reviewing = true;
|
|
1638
|
+
try {
|
|
1639
|
+
const ask = (await fetchInApp(identified).catch(() => null))?.review;
|
|
1640
|
+
if (!ask) return "not-now";
|
|
1641
|
+
const asked = await deps.storeReview.request().catch(() => false);
|
|
1642
|
+
record(REVIEW_EVENT, { campaign: ask.campaign, store: ask.store, action: asked ? "requested" : "unavailable" });
|
|
1643
|
+
void flush();
|
|
1644
|
+
return asked ? "requested" : "unavailable";
|
|
1645
|
+
} finally {
|
|
1646
|
+
reviewing = false;
|
|
1647
|
+
}
|
|
1648
|
+
};
|
|
1597
1649
|
let resolveReady = () => {
|
|
1598
1650
|
};
|
|
1599
1651
|
const ready = new Promise((r) => {
|
|
@@ -1723,13 +1775,14 @@ var createClient = (options, deps) => {
|
|
|
1723
1775
|
record("$screen", { ...props, path, screen: name, ...previous ? { previous } : {} });
|
|
1724
1776
|
recorder?.mark({ kind: "pageview", path });
|
|
1725
1777
|
},
|
|
1726
|
-
identify: (id, props) => {
|
|
1778
|
+
identify: (id, props, options2) => {
|
|
1727
1779
|
if (typeof id !== "string" || !id) return;
|
|
1728
1780
|
if (!loaded) {
|
|
1729
|
-
early.push(() => client.identify(id, props));
|
|
1781
|
+
early.push(() => client.identify(id, props, options2));
|
|
1730
1782
|
return;
|
|
1731
1783
|
}
|
|
1732
1784
|
const previous = sendId();
|
|
1785
|
+
signed = nextSigned(signed, id, options2?.hash, deps.log);
|
|
1733
1786
|
identified = id;
|
|
1734
1787
|
person = { ...props, id };
|
|
1735
1788
|
record("$identify", { ...props, id, ...previous && previous !== id ? { previousId: previous } : {} });
|
|
@@ -1743,7 +1796,9 @@ var createClient = (options, deps) => {
|
|
|
1743
1796
|
return;
|
|
1744
1797
|
}
|
|
1745
1798
|
if (pushToken) void unregisterForPush();
|
|
1799
|
+
void flush();
|
|
1746
1800
|
identified = void 0;
|
|
1801
|
+
signed = null;
|
|
1747
1802
|
person = void 0;
|
|
1748
1803
|
session = null;
|
|
1749
1804
|
utm = null;
|
|
@@ -1822,6 +1877,7 @@ var createClient = (options, deps) => {
|
|
|
1822
1877
|
paywall,
|
|
1823
1878
|
registerForPush,
|
|
1824
1879
|
unregisterForPush,
|
|
1880
|
+
requestReview,
|
|
1825
1881
|
flows,
|
|
1826
1882
|
flush,
|
|
1827
1883
|
ready,
|
|
@@ -1837,7 +1893,7 @@ var createClient = (options, deps) => {
|
|
|
1837
1893
|
if (!apiKey || consent === "off") return null;
|
|
1838
1894
|
const known = client.getUser();
|
|
1839
1895
|
const user = as?.name || as?.email ? { ...known, ...as.name ? { name: as.name } : {}, ...as.email ? { email: as.email } : {} } : known;
|
|
1840
|
-
return createApi({ host, apiKey, distinctId: distinctId(), user });
|
|
1896
|
+
return createApi({ host, apiKey, distinctId: distinctId(), user, userHash: hashOf(distinctId()) });
|
|
1841
1897
|
},
|
|
1842
1898
|
isSurveyDone: (id) => surveysDone.has(id),
|
|
1843
1899
|
markSurveyDone: (id) => {
|
|
@@ -2227,6 +2283,12 @@ try {
|
|
|
2227
2283
|
} catch {
|
|
2228
2284
|
expoLocalization = null;
|
|
2229
2285
|
}
|
|
2286
|
+
var expoStoreReview = null;
|
|
2287
|
+
try {
|
|
2288
|
+
expoStoreReview = require("expo-store-review");
|
|
2289
|
+
} catch {
|
|
2290
|
+
expoStoreReview = null;
|
|
2291
|
+
}
|
|
2230
2292
|
var viewShot = null;
|
|
2231
2293
|
try {
|
|
2232
2294
|
viewShot = require("react-native-view-shot");
|
|
@@ -2330,6 +2392,17 @@ var recorderDeps = () => {
|
|
|
2330
2392
|
masks: measureMasks
|
|
2331
2393
|
};
|
|
2332
2394
|
};
|
|
2395
|
+
var storeReview = () => {
|
|
2396
|
+
const m = expoStoreReview;
|
|
2397
|
+
if (!m?.requestReview) return null;
|
|
2398
|
+
return {
|
|
2399
|
+
request: async () => {
|
|
2400
|
+
if (m.isAvailableAsync && !await m.isAvailableAsync()) return false;
|
|
2401
|
+
await m.requestReview();
|
|
2402
|
+
return true;
|
|
2403
|
+
}
|
|
2404
|
+
};
|
|
2405
|
+
};
|
|
2333
2406
|
var nativeDeps = (overrides = {}) => ({
|
|
2334
2407
|
storage: overrides.storage !== void 0 ? overrides.storage : asyncStorage(),
|
|
2335
2408
|
fetch: ((url, init) => fetch(url, init)),
|
|
@@ -2344,6 +2417,7 @@ var nativeDeps = (overrides = {}) => ({
|
|
|
2344
2417
|
initialUrl: () => RN2.Linking.getInitialURL(),
|
|
2345
2418
|
openUrl: (url) => void RN2.Linking.openURL(url).catch(() => void 0),
|
|
2346
2419
|
push: expoPush(),
|
|
2420
|
+
storeReview: storeReview(),
|
|
2347
2421
|
recorder: recorderDeps()
|
|
2348
2422
|
});
|
|
2349
2423
|
var optionalModules = () => ({
|
|
@@ -2352,6 +2426,7 @@ var optionalModules = () => ({
|
|
|
2352
2426
|
expoApplication: !!expoApplication,
|
|
2353
2427
|
expoLocalization: !!expoLocalization,
|
|
2354
2428
|
expoNotifications: !!expoNotifications,
|
|
2429
|
+
expoStoreReview: !!expoStoreReview?.requestReview,
|
|
2355
2430
|
viewShot: !!viewShot?.captureScreen
|
|
2356
2431
|
});
|
|
2357
2432
|
|
|
@@ -3570,6 +3645,10 @@ var usePaywall = () => {
|
|
|
3570
3645
|
const client = useClient();
|
|
3571
3646
|
return { open: client.openPaywall };
|
|
3572
3647
|
};
|
|
3648
|
+
var useReview = () => {
|
|
3649
|
+
const client = useClient();
|
|
3650
|
+
return { request: client.requestReview };
|
|
3651
|
+
};
|
|
3573
3652
|
var useOnboarding = () => {
|
|
3574
3653
|
const client = useClient();
|
|
3575
3654
|
return { start: client.startOnboarding };
|