@wireai/activation 0.10.0 → 0.12.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/AGENTS.md +51 -0
- package/CHANGELOG.md +111 -1
- package/INTEGRATION_PROMPT.md +13 -1
- package/README.md +106 -4
- package/dist/analytics/index.d.mts +35 -6
- package/dist/analytics/index.d.ts +35 -6
- package/dist/analytics/index.js +222 -94
- package/dist/analytics/index.js.map +1 -1
- package/dist/analytics/index.mjs +214 -95
- package/dist/analytics/index.mjs.map +1 -1
- package/dist/{currentSession-D0Vq7_VE.d.ts → currentSession-D6RiVtc8.d.ts} +187 -29
- package/dist/{currentSession-DdDkprpM.d.mts → currentSession-DsSDHqor.d.mts} +187 -29
- package/dist/index.d.mts +236 -82
- package/dist/index.d.ts +236 -82
- package/dist/index.js +330 -60
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +314 -61
- package/dist/index.mjs.map +1 -1
- package/dist/questionnaire/index.d.mts +1 -1
- package/dist/questionnaire/index.d.ts +1 -1
- package/dist/questionnaire/index.js +59 -8
- package/dist/questionnaire/index.js.map +1 -1
- package/dist/questionnaire/index.mjs +59 -8
- package/dist/questionnaire/index.mjs.map +1 -1
- package/dist/reviews/index.d.mts +2 -2
- package/dist/reviews/index.d.ts +2 -2
- package/dist/reviews/index.js +97 -17
- package/dist/reviews/index.js.map +1 -1
- package/dist/reviews/index.mjs +97 -17
- package/dist/reviews/index.mjs.map +1 -1
- package/dist/{transport-Bzb-bcB2.d.mts → transport-CF_eHwzC.d.mts} +15 -16
- package/dist/{transport-B31G0Cib.d.ts → transport-DsRe4epC.d.ts} +15 -16
- package/llms.txt +9 -0
- package/package.json +1 -1
- package/src/activation/useWireActivation.ts +12 -1
- package/src/activation/wireActivation.ts +36 -24
- package/src/analytics/analyticsFacade.ts +113 -29
- package/src/analytics/currentSession.ts +83 -0
- package/src/analytics/eventQueue.ts +20 -11
- package/src/analytics/index.ts +29 -1
- package/src/analytics/reportClientEvent.ts +50 -2
- package/src/analytics/screenTracking.ts +6 -1
- package/src/analytics/useAnalytics.ts +22 -1
- package/src/context/deviceId.ts +109 -0
- package/src/context/userContext.ts +73 -0
- package/src/identity/userIdentity.ts +10 -0
- package/src/index.ts +50 -2
- package/src/questionnaire/runtime.ts +12 -2
- package/src/questionnaire/transport.ts +5 -1
- package/src/questionnaire/useQuestionnaireGate.ts +9 -7
- package/src/revenuecat/index.ts +55 -0
- package/src/revenuecat/purchaseEvents.ts +167 -0
- package/src/revenuecat/revenueCatBridge.ts +221 -0
- package/src/revenuecat/types.ts +95 -0
- package/src/reviews/decision.ts +8 -1
- package/src/reviews/runtime.ts +92 -1
- package/src/reviews/transport.ts +27 -10
- package/src/reviews/useReviewGate.ts +12 -7
- package/src/session-analytics/lifecycle.ts +15 -13
- package/src/session-analytics/reportSessionStart.ts +15 -4
- package/src/session-analytics/useLifecycleEvents.ts +68 -28
package/dist/index.mjs
CHANGED
|
@@ -1512,6 +1512,23 @@ var buildEventsRequest = (target, events) => {
|
|
|
1512
1512
|
return null;
|
|
1513
1513
|
}
|
|
1514
1514
|
};
|
|
1515
|
+
var warnOnSkippedEvents = (res) => {
|
|
1516
|
+
try {
|
|
1517
|
+
const json = res == null ? void 0 : res.json;
|
|
1518
|
+
if (typeof json !== "function") return;
|
|
1519
|
+
void Promise.resolve(json.call(res)).then((body) => {
|
|
1520
|
+
const skipped = body == null ? void 0 : body.skipped;
|
|
1521
|
+
if (typeof skipped !== "number" || skipped <= 0) return;
|
|
1522
|
+
if (typeof __DEV__ !== "undefined" && __DEV__ && typeof console !== "undefined" && console.warn) {
|
|
1523
|
+
console.warn(
|
|
1524
|
+
`[wireai] the server ACCEPTED the /v1/events POST but DISCARDED ${skipped} event(s) (skipped in the response body) \u2014 they are gone, not retried. The usual cause is an event with a missing or empty session_id.`
|
|
1525
|
+
);
|
|
1526
|
+
}
|
|
1527
|
+
}).catch(() => {
|
|
1528
|
+
});
|
|
1529
|
+
} catch {
|
|
1530
|
+
}
|
|
1531
|
+
};
|
|
1515
1532
|
var reportClientEvents = (target, events) => {
|
|
1516
1533
|
try {
|
|
1517
1534
|
const req = buildEventsRequest(target, events);
|
|
@@ -3308,6 +3325,28 @@ var getCurrentSessionId = () => globalSlot[CURRENT_SESSION_ID_SLOT];
|
|
|
3308
3325
|
var resetCurrentSessionId = () => {
|
|
3309
3326
|
globalSlot[CURRENT_SESSION_ID_SLOT] = void 0;
|
|
3310
3327
|
};
|
|
3328
|
+
var warnInDev = (message) => {
|
|
3329
|
+
if (typeof __DEV__ !== "undefined" && __DEV__ && typeof console !== "undefined" && console.warn) {
|
|
3330
|
+
console.warn(message);
|
|
3331
|
+
return true;
|
|
3332
|
+
}
|
|
3333
|
+
return false;
|
|
3334
|
+
};
|
|
3335
|
+
var MINT_WARNING = "[wireai] No app-open session was registered, so a session id was minted for this event (the server drops an event that has no session_id, and still answers 200). Mount useLifecycleEvents at your app root so events correlate to a real app-open.";
|
|
3336
|
+
var MINT_WARNED_SLOT = /* @__PURE__ */ Symbol.for(
|
|
3337
|
+
"@wireai/activation:currentSessionIdMintWarned"
|
|
3338
|
+
);
|
|
3339
|
+
var warnSlot = globalThis;
|
|
3340
|
+
var ensureCurrentSessionId = () => {
|
|
3341
|
+
const existing = globalSlot[CURRENT_SESSION_ID_SLOT];
|
|
3342
|
+
if (typeof existing === "string" && existing.length > 0) return existing;
|
|
3343
|
+
const minted = makeSessionId();
|
|
3344
|
+
globalSlot[CURRENT_SESSION_ID_SLOT] = minted;
|
|
3345
|
+
if (!warnSlot[MINT_WARNED_SLOT] && warnInDev(MINT_WARNING)) {
|
|
3346
|
+
warnSlot[MINT_WARNED_SLOT] = true;
|
|
3347
|
+
}
|
|
3348
|
+
return minted;
|
|
3349
|
+
};
|
|
3311
3350
|
|
|
3312
3351
|
// src/session/persistedSession.ts
|
|
3313
3352
|
var DEFAULT_SESSION_TTL_MS = 36e5;
|
|
@@ -3376,6 +3415,7 @@ var sanitizeUserId = (raw) => {
|
|
|
3376
3415
|
if (!trimmed) return void 0;
|
|
3377
3416
|
return trimmed.length > USER_ID_MAX_LENGTH ? trimmed.slice(0, USER_ID_MAX_LENGTH) : trimmed;
|
|
3378
3417
|
};
|
|
3418
|
+
var looksLikeEmail = (value) => typeof value === "string" && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value.trim());
|
|
3379
3419
|
var identifyOnboarding = async (opts) => {
|
|
3380
3420
|
var _a2, _b, _c;
|
|
3381
3421
|
const userId = sanitizeUserId(opts.userId);
|
|
@@ -4091,6 +4131,25 @@ var namespaceExtra = (extra) => {
|
|
|
4091
4131
|
}
|
|
4092
4132
|
return out;
|
|
4093
4133
|
};
|
|
4134
|
+
var analyticsUserIdStorageKey = (appId) => `wireai:analytics:userId:${appId != null ? appId : "default"}`;
|
|
4135
|
+
var clearPiiFromContext = (ctx = {}) => {
|
|
4136
|
+
const rest = {};
|
|
4137
|
+
if (typeof ctx.appVersion === "string") rest.appVersion = ctx.appVersion;
|
|
4138
|
+
if (typeof ctx.deviceKey === "string") rest.deviceKey = ctx.deviceKey;
|
|
4139
|
+
return rest;
|
|
4140
|
+
};
|
|
4141
|
+
var clearUserContext = async (opts = {}) => {
|
|
4142
|
+
const storage = opts.storage;
|
|
4143
|
+
if (!storage) return;
|
|
4144
|
+
try {
|
|
4145
|
+
await storage.removeItem(analyticsUserIdStorageKey(opts.appId));
|
|
4146
|
+
} catch {
|
|
4147
|
+
}
|
|
4148
|
+
};
|
|
4149
|
+
var activationJoinContext = (deviceKey) => {
|
|
4150
|
+
var _a2;
|
|
4151
|
+
return (_a2 = resolveUserContext({ deviceKey }).userContext) != null ? _a2 : {};
|
|
4152
|
+
};
|
|
4094
4153
|
var resolveUserContext = (ctx = {}, opts = {}) => {
|
|
4095
4154
|
var _a2;
|
|
4096
4155
|
const result = {};
|
|
@@ -4129,6 +4188,47 @@ var mintDeviceId = () => {
|
|
|
4129
4188
|
const time = Date.now().toString(36);
|
|
4130
4189
|
return `${AUTO_DEVICE_ID_PREFIX}${time}_${randomChunk()}${randomChunk()}`;
|
|
4131
4190
|
};
|
|
4191
|
+
var AUTO_DEVICE_KEY_SLOT = /* @__PURE__ */ Symbol.for("@wireai/activation:autoDeviceKeys");
|
|
4192
|
+
var deviceKeyGlobal = globalThis;
|
|
4193
|
+
var autoDeviceKeyRegistry = () => {
|
|
4194
|
+
const existing = deviceKeyGlobal[AUTO_DEVICE_KEY_SLOT];
|
|
4195
|
+
if (existing) return existing;
|
|
4196
|
+
const created = { keys: /* @__PURE__ */ new Map(), hydrating: /* @__PURE__ */ new Set() };
|
|
4197
|
+
deviceKeyGlobal[AUTO_DEVICE_KEY_SLOT] = created;
|
|
4198
|
+
return created;
|
|
4199
|
+
};
|
|
4200
|
+
var resolveAutoDeviceKey = (opts = {}) => {
|
|
4201
|
+
var _a2, _b;
|
|
4202
|
+
const registry = autoDeviceKeyRegistry();
|
|
4203
|
+
const appId = (_a2 = opts.appId) != null ? _a2 : "default";
|
|
4204
|
+
let id = registry.keys.get(appId);
|
|
4205
|
+
if (!id) {
|
|
4206
|
+
id = mintDeviceId();
|
|
4207
|
+
registry.keys.set(appId, id);
|
|
4208
|
+
}
|
|
4209
|
+
const storage = opts.storage;
|
|
4210
|
+
if (storage && !registry.hydrating.has(appId)) {
|
|
4211
|
+
registry.hydrating.add(appId);
|
|
4212
|
+
const slot = deviceIdStorageKey(appId);
|
|
4213
|
+
const minted = id;
|
|
4214
|
+
try {
|
|
4215
|
+
void Promise.resolve(storage.getItem(slot)).then((saved) => {
|
|
4216
|
+
const persisted = typeof saved === "string" && saved.trim() ? saved.trim() : void 0;
|
|
4217
|
+
if (persisted) registry.keys.set(appId, persisted);
|
|
4218
|
+
else void Promise.resolve(storage.setItem(slot, minted)).catch(() => {
|
|
4219
|
+
});
|
|
4220
|
+
}).catch(() => {
|
|
4221
|
+
});
|
|
4222
|
+
} catch {
|
|
4223
|
+
}
|
|
4224
|
+
}
|
|
4225
|
+
return (_b = registry.keys.get(appId)) != null ? _b : id;
|
|
4226
|
+
};
|
|
4227
|
+
var resetAutoDeviceKeys = () => {
|
|
4228
|
+
const registry = autoDeviceKeyRegistry();
|
|
4229
|
+
registry.keys.clear();
|
|
4230
|
+
registry.hydrating.clear();
|
|
4231
|
+
};
|
|
4132
4232
|
|
|
4133
4233
|
// src/activation/revalidation.ts
|
|
4134
4234
|
var REVALIDATION_SLOT = /* @__PURE__ */ Symbol.for(
|
|
@@ -4176,22 +4276,20 @@ var createWireActivation = (config) => {
|
|
|
4176
4276
|
var _a2, _b;
|
|
4177
4277
|
const target = { serverUrl: config.serverUrl, apiKey: config.apiKey };
|
|
4178
4278
|
const explicitDeviceKey = (_b = clean(config.deviceKey)) != null ? _b : clean((_a2 = config.userContext) == null ? void 0 : _a2.deviceKey);
|
|
4179
|
-
|
|
4180
|
-
|
|
4181
|
-
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
if (persisted) autoDeviceKey = persisted;
|
|
4186
|
-
else void storage.setItem(key, autoDeviceKey).catch(() => {
|
|
4187
|
-
});
|
|
4188
|
-
}).catch(() => {
|
|
4189
|
-
});
|
|
4190
|
-
}
|
|
4279
|
+
const autoDeviceKeyOptions = {
|
|
4280
|
+
appId: config.appId,
|
|
4281
|
+
// An explicit key opts out of minting AND persisting (unchanged contract).
|
|
4282
|
+
storage: explicitDeviceKey ? void 0 : config.storage
|
|
4283
|
+
};
|
|
4284
|
+
if (!explicitDeviceKey) resolveAutoDeviceKey(autoDeviceKeyOptions);
|
|
4191
4285
|
const applyContext = (event) => {
|
|
4192
4286
|
var _a3, _b2;
|
|
4193
4287
|
const resolved = resolveUserContext(
|
|
4194
|
-
|
|
4288
|
+
// `??` is lazy on purpose: an explicit key must never even touch the auto registry.
|
|
4289
|
+
{
|
|
4290
|
+
...(_a3 = config.userContext) != null ? _a3 : {},
|
|
4291
|
+
deviceKey: explicitDeviceKey != null ? explicitDeviceKey : resolveAutoDeviceKey(autoDeviceKeyOptions)
|
|
4292
|
+
},
|
|
4195
4293
|
{ autoAppVersion: config.appVersion }
|
|
4196
4294
|
);
|
|
4197
4295
|
if (resolved.userContext) {
|
|
@@ -4200,8 +4298,8 @@ var createWireActivation = (config) => {
|
|
|
4200
4298
|
if (resolved.userId && !event.user_id) event.user_id = resolved.userId;
|
|
4201
4299
|
};
|
|
4202
4300
|
const track = async (name2, meta) => {
|
|
4203
|
-
|
|
4204
|
-
|
|
4301
|
+
if (!clean(name2)) return false;
|
|
4302
|
+
const sessionId = ensureCurrentSessionId();
|
|
4205
4303
|
const event = {
|
|
4206
4304
|
event_type: "app_event",
|
|
4207
4305
|
session_id: sessionId,
|
|
@@ -4228,9 +4326,16 @@ var useActivationRevalidation = () => useSyncExternalStore(
|
|
|
4228
4326
|
getActivationRevalidationVersion
|
|
4229
4327
|
);
|
|
4230
4328
|
var useWireActivation = (config) => {
|
|
4329
|
+
var _a2;
|
|
4231
4330
|
const ref = useRef(void 0);
|
|
4232
4331
|
const prevKeys = useRef("");
|
|
4233
|
-
const currentKeys =
|
|
4332
|
+
const currentKeys = [
|
|
4333
|
+
config.serverUrl,
|
|
4334
|
+
config.apiKey,
|
|
4335
|
+
config.appId,
|
|
4336
|
+
config.deviceKey,
|
|
4337
|
+
(_a2 = config.userContext) == null ? void 0 : _a2.deviceKey
|
|
4338
|
+
].join("|");
|
|
4234
4339
|
if (!ref.current || prevKeys.current !== currentKeys) {
|
|
4235
4340
|
prevKeys.current = currentKeys;
|
|
4236
4341
|
ref.current = createWireActivation(config);
|
|
@@ -4239,6 +4344,154 @@ var useWireActivation = (config) => {
|
|
|
4239
4344
|
return { track: ref.current.track, sessionId: ref.current.sessionId, revalidation };
|
|
4240
4345
|
};
|
|
4241
4346
|
|
|
4347
|
+
// src/revenuecat/purchaseEvents.ts
|
|
4348
|
+
var WIRE_PURCHASE_EVENTS = {
|
|
4349
|
+
/** The paywall became visible (offerings loaded). */
|
|
4350
|
+
paywallShown: "wire_paywall_shown",
|
|
4351
|
+
/** The user tapped buy; the store sheet is about to open. */
|
|
4352
|
+
checkoutStarted: "wire_checkout_started",
|
|
4353
|
+
/** The store confirmed the purchase AND the entitlement is now active. */
|
|
4354
|
+
purchased: "wire_purchase_completed",
|
|
4355
|
+
/** The purchase did not land: a user cancel or a real store/network error (see `reason`). */
|
|
4356
|
+
purchaseFailed: "wire_purchase_failed",
|
|
4357
|
+
/** A restore ran (whether or not it produced an entitlement; see `plan_tier`). */
|
|
4358
|
+
restored: "wire_purchase_restored"
|
|
4359
|
+
};
|
|
4360
|
+
var PLAN_TIER_CONTEXT_KEY = "plan_tier";
|
|
4361
|
+
var asRecord = (value) => typeof value === "object" && value !== null ? value : void 0;
|
|
4362
|
+
var activeEntitlement = (info, entitlementId) => {
|
|
4363
|
+
var _a2, _b;
|
|
4364
|
+
const active = asRecord((_b = asRecord((_a2 = asRecord(info)) == null ? void 0 : _a2.entitlements)) == null ? void 0 : _b.active);
|
|
4365
|
+
const found = active == null ? void 0 : active[entitlementId];
|
|
4366
|
+
const entitlement = asRecord(found);
|
|
4367
|
+
if (!entitlement) return void 0;
|
|
4368
|
+
return entitlement.isActive === false ? void 0 : entitlement;
|
|
4369
|
+
};
|
|
4370
|
+
var isTrial = (entitlement) => typeof entitlement.periodType === "string" && entitlement.periodType.toUpperCase() === "TRIAL";
|
|
4371
|
+
var resolvePlanTier = (info, entitlementId) => {
|
|
4372
|
+
const entitlement = activeEntitlement(info, entitlementId);
|
|
4373
|
+
if (!entitlement) return "free";
|
|
4374
|
+
return isTrial(entitlement) ? "trial" : "paid";
|
|
4375
|
+
};
|
|
4376
|
+
var describePackage = (pkg) => {
|
|
4377
|
+
const props = {};
|
|
4378
|
+
if (!pkg) return props;
|
|
4379
|
+
if (typeof pkg.identifier === "string") props.package_id = pkg.identifier;
|
|
4380
|
+
if (typeof pkg.packageType === "string") props.package_type = pkg.packageType;
|
|
4381
|
+
if (typeof pkg.offeringIdentifier === "string") props.offering_id = pkg.offeringIdentifier;
|
|
4382
|
+
const product = asRecord(pkg.product);
|
|
4383
|
+
if (product) {
|
|
4384
|
+
if (typeof product.identifier === "string") props.product_id = product.identifier;
|
|
4385
|
+
if (typeof product.price === "number" && Number.isFinite(product.price)) {
|
|
4386
|
+
props.price = product.price;
|
|
4387
|
+
}
|
|
4388
|
+
if (typeof product.currencyCode === "string") props.currency = product.currencyCode;
|
|
4389
|
+
}
|
|
4390
|
+
return props;
|
|
4391
|
+
};
|
|
4392
|
+
var describeEntitlement = (info, entitlementId) => {
|
|
4393
|
+
const entitlement = activeEntitlement(info, entitlementId);
|
|
4394
|
+
const props = {
|
|
4395
|
+
entitlement: entitlementId,
|
|
4396
|
+
plan_tier: entitlement ? isTrial(entitlement) ? "trial" : "paid" : "free"
|
|
4397
|
+
};
|
|
4398
|
+
if (!entitlement) return props;
|
|
4399
|
+
if (typeof entitlement.periodType === "string") props.period_type = entitlement.periodType;
|
|
4400
|
+
props.is_trial = isTrial(entitlement);
|
|
4401
|
+
if (typeof entitlement.willRenew === "boolean") props.will_renew = entitlement.willRenew;
|
|
4402
|
+
if (typeof entitlement.store === "string") props.store = entitlement.store;
|
|
4403
|
+
if (typeof entitlement.productIdentifier === "string") {
|
|
4404
|
+
props.product_id = entitlement.productIdentifier;
|
|
4405
|
+
}
|
|
4406
|
+
if (typeof entitlement.isSandbox === "boolean") props.is_sandbox = entitlement.isSandbox;
|
|
4407
|
+
return props;
|
|
4408
|
+
};
|
|
4409
|
+
var PURCHASE_CANCELLED_CODE = "1";
|
|
4410
|
+
var isUserCancelled = (error) => {
|
|
4411
|
+
const record = asRecord(error);
|
|
4412
|
+
if (!record) return false;
|
|
4413
|
+
if (record.userCancelled === true) return true;
|
|
4414
|
+
return record.code === PURCHASE_CANCELLED_CODE;
|
|
4415
|
+
};
|
|
4416
|
+
var describeFailure = (error) => {
|
|
4417
|
+
const record = asRecord(error);
|
|
4418
|
+
const code = typeof (record == null ? void 0 : record.code) === "string" ? record.code : "unknown";
|
|
4419
|
+
return { reason: isUserCancelled(error) ? "cancelled" : "error", code };
|
|
4420
|
+
};
|
|
4421
|
+
|
|
4422
|
+
// src/revenuecat/revenueCatBridge.ts
|
|
4423
|
+
var createRevenueCatBridge = (config) => {
|
|
4424
|
+
const { analytics, entitlementId } = config;
|
|
4425
|
+
const writeTier = config.writePlanTier !== false;
|
|
4426
|
+
const emit = (event, props) => {
|
|
4427
|
+
try {
|
|
4428
|
+
const result = analytics.track(event, { ...config.commonProps, ...props });
|
|
4429
|
+
if (result && typeof result.catch === "function") {
|
|
4430
|
+
void result.catch(() => {
|
|
4431
|
+
});
|
|
4432
|
+
}
|
|
4433
|
+
} catch {
|
|
4434
|
+
}
|
|
4435
|
+
};
|
|
4436
|
+
const syncPlanTier = (customerInfo) => {
|
|
4437
|
+
var _a2;
|
|
4438
|
+
const tier = resolvePlanTier(customerInfo, entitlementId);
|
|
4439
|
+
if (!writeTier) return tier;
|
|
4440
|
+
try {
|
|
4441
|
+
(_a2 = analytics.setUserContext) == null ? void 0 : _a2.call(analytics, { extra: { [PLAN_TIER_CONTEXT_KEY]: tier } });
|
|
4442
|
+
} catch {
|
|
4443
|
+
}
|
|
4444
|
+
return tier;
|
|
4445
|
+
};
|
|
4446
|
+
const paywallShown = (offering, props) => {
|
|
4447
|
+
var _a2, _b;
|
|
4448
|
+
const shown = {
|
|
4449
|
+
packages_count: (_b = (_a2 = offering == null ? void 0 : offering.availablePackages) == null ? void 0 : _a2.length) != null ? _b : 0
|
|
4450
|
+
};
|
|
4451
|
+
if (typeof (offering == null ? void 0 : offering.identifier) === "string") shown.offering_id = offering.identifier;
|
|
4452
|
+
emit(WIRE_PURCHASE_EVENTS.paywallShown, { ...shown, ...props });
|
|
4453
|
+
};
|
|
4454
|
+
const checkoutStarted = (pkg, props) => {
|
|
4455
|
+
emit(WIRE_PURCHASE_EVENTS.checkoutStarted, { ...describePackage(pkg), ...props });
|
|
4456
|
+
};
|
|
4457
|
+
const purchaseCompleted = (customerInfo, pkg, props) => {
|
|
4458
|
+
const tier = syncPlanTier(customerInfo);
|
|
4459
|
+
const entitled = tier !== "free";
|
|
4460
|
+
if (entitled) {
|
|
4461
|
+
emit(WIRE_PURCHASE_EVENTS.purchased, {
|
|
4462
|
+
...describePackage(pkg),
|
|
4463
|
+
...describeEntitlement(customerInfo, entitlementId),
|
|
4464
|
+
...props
|
|
4465
|
+
});
|
|
4466
|
+
return true;
|
|
4467
|
+
}
|
|
4468
|
+
emit(WIRE_PURCHASE_EVENTS.purchaseFailed, {
|
|
4469
|
+
...describePackage(pkg),
|
|
4470
|
+
reason: "not_entitled",
|
|
4471
|
+
code: "unknown",
|
|
4472
|
+
entitlement: entitlementId,
|
|
4473
|
+
...props
|
|
4474
|
+
});
|
|
4475
|
+
return false;
|
|
4476
|
+
};
|
|
4477
|
+
const purchaseFailed = (error, pkg, props) => {
|
|
4478
|
+
emit(WIRE_PURCHASE_EVENTS.purchaseFailed, {
|
|
4479
|
+
...describePackage(pkg),
|
|
4480
|
+
...describeFailure(error),
|
|
4481
|
+
...props
|
|
4482
|
+
});
|
|
4483
|
+
};
|
|
4484
|
+
const purchasesRestored = (customerInfo, props) => {
|
|
4485
|
+
const tier = syncPlanTier(customerInfo);
|
|
4486
|
+
emit(WIRE_PURCHASE_EVENTS.restored, {
|
|
4487
|
+
...describeEntitlement(customerInfo, entitlementId),
|
|
4488
|
+
...props
|
|
4489
|
+
});
|
|
4490
|
+
return tier !== "free";
|
|
4491
|
+
};
|
|
4492
|
+
return { paywallShown, checkoutStarted, purchaseCompleted, purchaseFailed, purchasesRestored, syncPlanTier };
|
|
4493
|
+
};
|
|
4494
|
+
|
|
4242
4495
|
// src/session-analytics/reportSessionStart.ts
|
|
4243
4496
|
var SESSION_STARTED_EVENT = "app.session_started";
|
|
4244
4497
|
var _emitted = /* @__PURE__ */ new Set();
|
|
@@ -4291,6 +4544,8 @@ var reportSessionStart = (opts) => {
|
|
|
4291
4544
|
method: "POST",
|
|
4292
4545
|
headers,
|
|
4293
4546
|
body: JSON.stringify({ events: [event] })
|
|
4547
|
+
}).then((res) => {
|
|
4548
|
+
warnOnSkippedEvents(res);
|
|
4294
4549
|
}).catch(() => {
|
|
4295
4550
|
});
|
|
4296
4551
|
} catch {
|
|
@@ -4384,16 +4639,9 @@ var routeLifecycleEvent = (event, opts) => {
|
|
|
4384
4639
|
opts.sink(event);
|
|
4385
4640
|
return;
|
|
4386
4641
|
}
|
|
4387
|
-
const
|
|
4388
|
-
if (!
|
|
4389
|
-
|
|
4390
|
-
const headers = { "Content-Type": "application/json" };
|
|
4391
|
-
if (target.apiKey) headers.Authorization = `Bearer ${target.apiKey}`;
|
|
4392
|
-
void fetch(url, {
|
|
4393
|
-
method: "POST",
|
|
4394
|
-
headers,
|
|
4395
|
-
body: JSON.stringify({ events: [event] })
|
|
4396
|
-
}).catch(() => {
|
|
4642
|
+
const req = buildEventsRequest(opts.target, [event]);
|
|
4643
|
+
if (!req) return;
|
|
4644
|
+
void fetch(req.url, req.init).catch(() => {
|
|
4397
4645
|
});
|
|
4398
4646
|
} catch {
|
|
4399
4647
|
}
|
|
@@ -4428,11 +4676,13 @@ var reportFirstOpen = (opts) => {
|
|
|
4428
4676
|
})();
|
|
4429
4677
|
};
|
|
4430
4678
|
var wireLifecycleEvents = (opts) => {
|
|
4431
|
-
|
|
4679
|
+
var _a2;
|
|
4680
|
+
const sessionId = (_a2 = opts.sessionId) != null ? _a2 : makeSessionId();
|
|
4681
|
+
reportFirstOpen({ ...opts, sessionId });
|
|
4432
4682
|
reportSessionStart({
|
|
4433
4683
|
target: opts.target,
|
|
4434
4684
|
sink: opts.sink,
|
|
4435
|
-
sessionId
|
|
4685
|
+
sessionId,
|
|
4436
4686
|
userId: opts.userId,
|
|
4437
4687
|
deviceKey: opts.deviceKey,
|
|
4438
4688
|
sessionCount: opts.sessionCount,
|
|
@@ -4505,6 +4755,7 @@ var createEventQueue = (options) => {
|
|
|
4505
4755
|
var _a3;
|
|
4506
4756
|
const env = resolveEnvelope();
|
|
4507
4757
|
const stamped = { ...event };
|
|
4758
|
+
if (stamped.ts === void 0) stamped.ts = Date.now();
|
|
4508
4759
|
if (!env) return stamped;
|
|
4509
4760
|
if (!stamped.device && env.device) stamped.device = env.device;
|
|
4510
4761
|
if (!stamped.session_id && env.sessionId) stamped.session_id = env.sessionId;
|
|
@@ -4560,19 +4811,13 @@ var createEventQueue = (options) => {
|
|
|
4560
4811
|
}
|
|
4561
4812
|
})();
|
|
4562
4813
|
const postBatch = async (events) => {
|
|
4563
|
-
|
|
4814
|
+
const req = buildEventsRequest(target, events);
|
|
4815
|
+
if (!req) return false;
|
|
4564
4816
|
const controller = typeof AbortController !== "undefined" ? new AbortController() : void 0;
|
|
4565
4817
|
const timer = setTimeout(() => controller == null ? void 0 : controller.abort(), 15e3);
|
|
4566
4818
|
try {
|
|
4567
|
-
const
|
|
4568
|
-
|
|
4569
|
-
if (target.apiKey) headers.Authorization = `Bearer ${target.apiKey}`;
|
|
4570
|
-
const res = await fetch(url, {
|
|
4571
|
-
method: "POST",
|
|
4572
|
-
headers,
|
|
4573
|
-
body: JSON.stringify({ events }),
|
|
4574
|
-
signal: controller == null ? void 0 : controller.signal
|
|
4575
|
-
});
|
|
4819
|
+
const res = await fetch(req.url, { ...req.init, signal: controller == null ? void 0 : controller.signal });
|
|
4820
|
+
warnOnSkippedEvents(res);
|
|
4576
4821
|
return !!(res && res.ok);
|
|
4577
4822
|
} catch {
|
|
4578
4823
|
return false;
|
|
@@ -4678,6 +4923,34 @@ var useLifecycleEvents = (config, options = {}) => {
|
|
|
4678
4923
|
var _a3;
|
|
4679
4924
|
return (cfg == null ? void 0 : cfg.serverUrl) ? { serverUrl: cfg.serverUrl, apiKey: (_a3 = cfg.apiKey) != null ? _a3 : "" } : void 0;
|
|
4680
4925
|
};
|
|
4926
|
+
const resolveDeviceKey = (cfg, opts) => {
|
|
4927
|
+
const host = typeof opts.deviceKey === "string" && opts.deviceKey.trim() ? opts.deviceKey : void 0;
|
|
4928
|
+
if (host) return host;
|
|
4929
|
+
if (!(cfg == null ? void 0 : cfg.storage)) return void 0;
|
|
4930
|
+
return resolveAutoDeviceKey({ appId: cfg.appId, storage: cfg.storage });
|
|
4931
|
+
};
|
|
4932
|
+
const mountOpenSessionId = makeSessionId();
|
|
4933
|
+
const fireSession = (sessionId) => {
|
|
4934
|
+
var _a3;
|
|
4935
|
+
const { config: cfg, options: opts } = latest.current;
|
|
4936
|
+
if (opts.enabled === false) return;
|
|
4937
|
+
if (!(cfg == null ? void 0 : cfg.serverUrl) && !opts.sink) return;
|
|
4938
|
+
const device = collectDeviceContext();
|
|
4939
|
+
if (cfg == null ? void 0 : cfg.appVersion) device.appVersion = cfg.appVersion;
|
|
4940
|
+
reportSessionStart({
|
|
4941
|
+
target: targetOf(cfg),
|
|
4942
|
+
sink: resolveSink(),
|
|
4943
|
+
sessionId,
|
|
4944
|
+
userId: opts.userId,
|
|
4945
|
+
deviceKey: resolveDeviceKey(cfg, opts),
|
|
4946
|
+
sessionCount: opts.sessionCount,
|
|
4947
|
+
appVersion: (_a3 = cfg == null ? void 0 : cfg.appVersion) != null ? _a3 : device.appVersion,
|
|
4948
|
+
platform: Platform.OS,
|
|
4949
|
+
device,
|
|
4950
|
+
meta: opts.meta
|
|
4951
|
+
});
|
|
4952
|
+
};
|
|
4953
|
+
fireSession(mountOpenSessionId);
|
|
4681
4954
|
{
|
|
4682
4955
|
const { config: cfg, options: opts } = latest.current;
|
|
4683
4956
|
if (opts.enabled !== false) {
|
|
@@ -4686,10 +4959,11 @@ var useLifecycleEvents = (config, options = {}) => {
|
|
|
4686
4959
|
reportFirstOpen({
|
|
4687
4960
|
target: targetOf(cfg),
|
|
4688
4961
|
sink: resolveSink(),
|
|
4962
|
+
sessionId: mountOpenSessionId,
|
|
4689
4963
|
storage: cfg == null ? void 0 : cfg.storage,
|
|
4690
4964
|
appId: cfg == null ? void 0 : cfg.appId,
|
|
4691
4965
|
userId: opts.userId,
|
|
4692
|
-
deviceKey: opts
|
|
4966
|
+
deviceKey: resolveDeviceKey(cfg, opts),
|
|
4693
4967
|
sessionCount: opts.sessionCount,
|
|
4694
4968
|
appVersion: (_a2 = cfg == null ? void 0 : cfg.appVersion) != null ? _a2 : device.appVersion,
|
|
4695
4969
|
platform: Platform.OS,
|
|
@@ -4698,27 +4972,6 @@ var useLifecycleEvents = (config, options = {}) => {
|
|
|
4698
4972
|
});
|
|
4699
4973
|
}
|
|
4700
4974
|
}
|
|
4701
|
-
const fireSession = () => {
|
|
4702
|
-
var _a3;
|
|
4703
|
-
const { config: cfg, options: opts } = latest.current;
|
|
4704
|
-
if (opts.enabled === false) return;
|
|
4705
|
-
if (!(cfg == null ? void 0 : cfg.serverUrl) && !opts.sink) return;
|
|
4706
|
-
const device = collectDeviceContext();
|
|
4707
|
-
if (cfg == null ? void 0 : cfg.appVersion) device.appVersion = cfg.appVersion;
|
|
4708
|
-
reportSessionStart({
|
|
4709
|
-
target: targetOf(cfg),
|
|
4710
|
-
sink: resolveSink(),
|
|
4711
|
-
// A fresh per-open id each fire; the emitter's once-guard dedupes within the open.
|
|
4712
|
-
userId: opts.userId,
|
|
4713
|
-
deviceKey: opts.deviceKey,
|
|
4714
|
-
sessionCount: opts.sessionCount,
|
|
4715
|
-
appVersion: (_a3 = cfg == null ? void 0 : cfg.appVersion) != null ? _a3 : device.appVersion,
|
|
4716
|
-
platform: Platform.OS,
|
|
4717
|
-
device,
|
|
4718
|
-
meta: opts.meta
|
|
4719
|
-
});
|
|
4720
|
-
};
|
|
4721
|
-
fireSession();
|
|
4722
4975
|
let backgroundedAt = null;
|
|
4723
4976
|
const onChange = (state) => {
|
|
4724
4977
|
if (state === "background" || state === "inactive") {
|
|
@@ -4738,6 +4991,6 @@ var useLifecycleEvents = (config, options = {}) => {
|
|
|
4738
4991
|
}, []);
|
|
4739
4992
|
};
|
|
4740
4993
|
|
|
4741
|
-
export { AUTO_DEVICE_ID_PREFIX, AnimatedSparkle, BACKGROUND_SESSION_MS, CardGridSelectCard, CardHandoff, CenteredModal, ChipSelectCard, CompletionView, DEFAULT_FEATURES_TTL_MS, DEFAULT_SESSION_TTL_MS, DemoOnboarding, DoneBlock, EXTRA_KEY_PREFIX, ErrorBlock, FIRST_OPEN_EVENT, IconRegistryProvider, IllustrationProvider, InterstitialCard, LoadingBlock, LoadingScreen, NumberStepperCard, Button as OnboardingButton, OnboardingFlow, OnboardingScaffold, OnboardingThemeProvider, RESERVED_USER_CONTEXT_KEYS, SESSION_STARTED_EVENT, SelectionCard, StatusCard, StepProgress, TextInputCard, USER_ID_MAX_LENGTH, WIRE_ICON_GLYPHS, WIRE_ICON_NAMES, WIRE_ONBOARDING_EVENTS, WireFeaturesProvider, WireIcon, WireOnboarding, attributionMetadata, bumpActivationRevalidation, clearPersistedSession, collectDeviceContext, createWireActivation, defaultIllustrations, defaultOnboardingTheme, defaultWireFeatures, deriveAnswers, detectAppVersion, detectNativeModel, deviceIdStorageKey, featuresCacheKey, featuresEqual, fetchWireFeatures, firstOpenStorageKey, getActivationRevalidationVersion, getCurrentSessionId, hashEmailFnv1a, identifyOnboarding, isFeaturesFresh, isOnboardingEnabled, isWireScalar, loadPersistedSession, lookupIconGlyph, makeSessionId, mergeTheme, mintDeviceId, motionSpec_exports as motionSpec, namespaceExtra, onboardingComponents, parseWireFeatures, peekPersistedSession, readCachedFeatures, readProgress, reportClientEvent, reportClientEventAwait, reportClientEvents, reportClientEventsAwait, reportFirstOpen, reportSessionStart, resetActivationRevalidation, resetCurrentSessionId, resetFirstOpenLatch, resetSessionStartGuard, resolveUserContext, sanitizeUserId, savePersistedSession, sessionStorageKey, setCurrentSessionId, subscribeActivationRevalidation, themeFromBrand, toAnalyticsEvent, useActivationRevalidation, useHostIcon, useIllustration, useLifecycleEvents, useOnboardingTheme, useReducedMotion, useResolvedFeatures, useSessionStart, useWireActivation, useWireFeatures, useWireFeaturesContext, wireConfigFromEnv, wireLifecycleEvents, writeCachedFeatures };
|
|
4994
|
+
export { AUTO_DEVICE_ID_PREFIX, AnimatedSparkle, BACKGROUND_SESSION_MS, CardGridSelectCard, CardHandoff, CenteredModal, ChipSelectCard, CompletionView, DEFAULT_FEATURES_TTL_MS, DEFAULT_SESSION_TTL_MS, DemoOnboarding, DoneBlock, EXTRA_KEY_PREFIX, ErrorBlock, FIRST_OPEN_EVENT, IconRegistryProvider, IllustrationProvider, InterstitialCard, LoadingBlock, LoadingScreen, NumberStepperCard, Button as OnboardingButton, OnboardingFlow, OnboardingScaffold, OnboardingThemeProvider, PLAN_TIER_CONTEXT_KEY, RESERVED_USER_CONTEXT_KEYS, SESSION_STARTED_EVENT, SelectionCard, StatusCard, StepProgress, TextInputCard, USER_ID_MAX_LENGTH, WIRE_ICON_GLYPHS, WIRE_ICON_NAMES, WIRE_ONBOARDING_EVENTS, WIRE_PURCHASE_EVENTS, WireFeaturesProvider, WireIcon, WireOnboarding, activationJoinContext, activeEntitlement, analyticsUserIdStorageKey, attributionMetadata, bumpActivationRevalidation, clearPersistedSession, clearPiiFromContext, clearUserContext, collectDeviceContext, createRevenueCatBridge, createWireActivation, defaultIllustrations, defaultOnboardingTheme, defaultWireFeatures, deriveAnswers, describeEntitlement, describeFailure, describePackage, detectAppVersion, detectNativeModel, deviceIdStorageKey, ensureCurrentSessionId, featuresCacheKey, featuresEqual, fetchWireFeatures, firstOpenStorageKey, getActivationRevalidationVersion, getCurrentSessionId, hashEmailFnv1a, identifyOnboarding, isFeaturesFresh, isOnboardingEnabled, isUserCancelled, isWireScalar, loadPersistedSession, looksLikeEmail, lookupIconGlyph, makeSessionId, mergeTheme, mintDeviceId, motionSpec_exports as motionSpec, namespaceExtra, onboardingComponents, parseWireFeatures, peekPersistedSession, readCachedFeatures, readProgress, reportClientEvent, reportClientEventAwait, reportClientEvents, reportClientEventsAwait, reportFirstOpen, reportSessionStart, resetActivationRevalidation, resetAutoDeviceKeys, resetCurrentSessionId, resetFirstOpenLatch, resetSessionStartGuard, resolveAutoDeviceKey, resolvePlanTier, resolveUserContext, sanitizeUserId, savePersistedSession, sessionStorageKey, setCurrentSessionId, subscribeActivationRevalidation, themeFromBrand, toAnalyticsEvent, useActivationRevalidation, useHostIcon, useIllustration, useLifecycleEvents, useOnboardingTheme, useReducedMotion, useResolvedFeatures, useSessionStart, useWireActivation, useWireFeatures, useWireFeaturesContext, wireConfigFromEnv, wireLifecycleEvents, writeCachedFeatures };
|
|
4742
4995
|
//# sourceMappingURL=index.mjs.map
|
|
4743
4996
|
//# sourceMappingURL=index.mjs.map
|