@wireai/activation 0.14.2 → 0.15.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 (67) hide show
  1. package/AGENTS.md +1 -1
  2. package/CHANGELOG.md +144 -0
  3. package/README.md +23 -9
  4. package/dist/analytics/index.d.mts +5 -5
  5. package/dist/analytics/index.d.ts +5 -5
  6. package/dist/analytics/index.js.map +1 -1
  7. package/dist/analytics/index.mjs.map +1 -1
  8. package/dist/coachmarks/index.d.mts +13 -5
  9. package/dist/coachmarks/index.d.ts +13 -5
  10. package/dist/coachmarks/index.js +252 -58
  11. package/dist/coachmarks/index.js.map +1 -1
  12. package/dist/coachmarks/index.mjs +204 -9
  13. package/dist/coachmarks/index.mjs.map +1 -1
  14. package/dist/{currentSession-CW_5Mq4O.d.ts → currentSession-CFSRZ2wg.d.ts} +10 -4
  15. package/dist/{currentSession-CUvTOchb.d.mts → currentSession-orZy5p1e.d.mts} +10 -4
  16. package/dist/{decision-Bgo17oH7.d.mts → decision-3vWLuBlO.d.ts} +11 -2
  17. package/dist/{decision-Bkh_LigV.d.ts → decision-yBj2AyPW.d.mts} +11 -2
  18. package/dist/index.d.mts +2 -2
  19. package/dist/index.d.ts +2 -2
  20. package/dist/index.js.map +1 -1
  21. package/dist/index.mjs.map +1 -1
  22. package/dist/questionnaire/index.d.mts +3 -3
  23. package/dist/questionnaire/index.d.ts +3 -3
  24. package/dist/questionnaire/index.js +48 -3
  25. package/dist/questionnaire/index.js.map +1 -1
  26. package/dist/questionnaire/index.mjs +48 -3
  27. package/dist/questionnaire/index.mjs.map +1 -1
  28. package/dist/reviews/index.d.mts +10 -6
  29. package/dist/reviews/index.d.ts +10 -6
  30. package/dist/reviews/index.js +167 -18
  31. package/dist/reviews/index.js.map +1 -1
  32. package/dist/reviews/index.mjs +167 -18
  33. package/dist/reviews/index.mjs.map +1 -1
  34. package/dist/showcase/index.d.mts +1 -1
  35. package/dist/showcase/index.d.ts +1 -1
  36. package/dist/showcase/index.js +282 -48
  37. package/dist/showcase/index.js.map +1 -1
  38. package/dist/showcase/index.mjs +248 -12
  39. package/dist/showcase/index.mjs.map +1 -1
  40. package/dist/{transport-j5gFfJhK.d.mts → transport-s5QxA-ci.d.mts} +18 -13
  41. package/dist/{transport-B_0SgCBe.d.ts → transport-xqqSFqxs.d.ts} +18 -13
  42. package/dist/{types-Cju-1_jT.d.mts → types-Byx306Kv.d.mts} +25 -10
  43. package/dist/{types-BcmagF6K.d.mts → types-D_0B0yay.d.mts} +7 -2
  44. package/dist/{types-BcmagF6K.d.ts → types-D_0B0yay.d.ts} +7 -2
  45. package/dist/{types-h2BZvl1t.d.ts → types-tdATL5z0.d.ts} +25 -10
  46. package/metro/index.js +16 -5
  47. package/package.json +1 -1
  48. package/src/WireOnboarding.tsx +4 -1
  49. package/src/coachmarks/GestureHint.tsx +16 -7
  50. package/src/coachmarks/SpotlightOverlay.tsx +19 -13
  51. package/src/coachmarks/index.ts +7 -2
  52. package/src/coachmarks/reanimated.ts +342 -0
  53. package/src/coachmarks/runtime.ts +103 -2
  54. package/src/coachmarks/types.ts +7 -2
  55. package/src/context/deviceId.ts +32 -0
  56. package/src/reviews/ReviewGate.tsx +86 -37
  57. package/src/reviews/decision.ts +11 -1
  58. package/src/reviews/idempotency.ts +71 -0
  59. package/src/reviews/index.ts +4 -2
  60. package/src/reviews/runtime.ts +5 -3
  61. package/src/reviews/transport.ts +17 -12
  62. package/src/reviews/types.ts +7 -0
  63. package/src/showcase/FeatureShowcase.tsx +25 -9
  64. package/src/showcase/blazejOnboarding.ts +136 -0
  65. package/src/showcase/index.ts +8 -4
  66. package/src/types.ts +10 -4
  67. package/src/utils/submitResult.ts +17 -9
package/src/types.ts CHANGED
@@ -256,8 +256,11 @@ export type WireOnboardingProps = {
256
256
  *
257
257
  * SINCE 0.12.2, leaving it out no longer silently empties the funnel: when you pass `storage` and
258
258
  * this prop carries no `device_key`, the kit injects its OWN per-install key — the same one the
259
- * analytics surfaces mint and persist — so the default wiring joins. Anything you DO pass wins
260
- * verbatim and is never touched. See `autoJoinKey` for the opt-out and the two cases where the kit
259
+ * analytics surfaces mint and persist — so the default wiring joins. A `device_key` you DO pass
260
+ * wins verbatim and is never touched, provided it is a string with at least one non-whitespace
261
+ * character (`resolveIdentity`) — this map also accepts numbers and booleans, and a non-string or
262
+ * all-whitespace value is not a usable join key, so it is read as absent and the auto key is
263
+ * merged over it. See `autoJoinKey` for the opt-out and the two cases where the kit
261
264
  * still cannot fill the gap (no `storage`, or you opted out), which keep warning in dev.
262
265
  *
263
266
  * Never hand-write `userContext={{ deviceKey }}`: the server's device lookup reads `device_key`,
@@ -284,8 +287,11 @@ export type WireOnboardingProps = {
284
287
  * `autoJoinKey={false}` if you genuinely want an UNLINKED onboarding session; that restores the
285
288
  * pre-0.12.2 behavior exactly (nothing injected) and the dev warning fires again.
286
289
  *
287
- * Two things this flag does NOT do. It never overrides a `device_key` you passed — a host-supplied
288
- * key always wins, whatever this is set to. And it cannot conjure a key without `storage`: with no
290
+ * Two things this flag does NOT do. It never overrides a `device_key` you actually supplied — a
291
+ * host-supplied key always wins, whatever this is set to, where "supplied" means a string with at
292
+ * least one non-whitespace character (`resolveIdentity`); a non-string or an all-whitespace value
293
+ * is read as absent and the auto key is merged over it. And it cannot conjure a key without
294
+ * `storage`: with no
289
295
  * persistence the kit's id is minted fresh every launch, and a per-launch key corrupts
290
296
  * `min_sessions` instead of merely leaving the join empty, so the kit declines to inject and warns
291
297
  * in dev instead.
@@ -21,19 +21,27 @@
21
21
  *
22
22
  * `submitReview` was a boolean for exactly one unpublished release, and the boolean WAS the bug.
23
23
  * `false` meant both "nothing reached the server" and "the server answered non-2xx", and the caller
24
- * treats `false` as "still owed" and re-posts. But the server mints its own row id
25
- * (`create_review` / `_new_id()`), and neither `CreateReviewRequest` nor the questionnaire response
26
- * body carries a client id, so there is NO idempotency key on the wire: a 502 returned AFTER the
27
- * insert commits means the re-post writes a SECOND row. A response of any status proves the server
28
- * was reached, and that is a different question from whether it liked the payload.
24
+ * treats `false` as "still owed" and re-posts. At the time neither body carried a client id, so
25
+ * there was NO idempotency key on the wire on either surface: a 502 returned AFTER the insert
26
+ * commits meant the re-post wrote a SECOND row. A response of any status proves the server was
27
+ * reached, and that is a different question from whether it liked the payload which is why the
28
+ * three values stay, on both surfaces, whatever the wire gains.
29
29
  *
30
30
  * ── THE RESIDUAL, STATED HONESTLY ─────────────────────────────────────────────────────────────
31
31
  *
32
32
  * `unsent` is not proof the server never got it. A connection dropped after the request was written
33
33
  * — or after the row committed — surfaces as a thrown/rejected `fetch`, exactly like an offline
34
- * device. Retrying only on `unsent` is therefore SAFER, not SAFE. Closing that window needs a
35
- * CLIENT-MINTED IDEMPOTENCY KEY the server upserts on, which is a server change and not something
36
- * the kit can fake. Until it exists, prefer losing a row over inventing one: a lost detractor is a
37
- * gap in the data, a duplicated one is a lie in the data.
34
+ * device. Closing that window needs a client-minted idempotency key the server upserts on, and AS
35
+ * OF 2026-08-19 THE TWO SURFACES DIFFER do not read this paragraph as one fact about both:
36
+ *
37
+ * REVIEWS closed. `CreateReviewRequest` takes an optional `idempotency_key` and the server
38
+ * upserts a derived row on it, so a `ReviewGate` re-post merges instead of duplicating. It is a
39
+ * capability, not a guarantee: the server honours the key only when the post also carries a
40
+ * unit to scope it to (`meta.device_key`, else `session_id`), so a caller that strips both is
41
+ * back to the old behaviour.
42
+ * • QUESTIONNAIRES — still open, and still exactly as this paragraph used to read for both. The
43
+ * response body carries no client id and the server has no idempotency path for it at all, so
44
+ * retrying only on `unsent` there is SAFER, not SAFE. Prefer losing a row over inventing one: a
45
+ * lost detractor is a gap in the data, a duplicated one is a lie in the data.
38
46
  */
39
47
  export type SubmitResult = "accepted" | "rejected" | "unsent";