@monetize.software/sdk 3.0.0-alpha.9 → 3.0.0-beta.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 (212) hide show
  1. package/dist/chunks/PaywallUI-CCwYgagL.js +26 -0
  2. package/dist/chunks/PaywallUI-CCwYgagL.js.map +1 -0
  3. package/dist/chunks/PaywallUI-CDlJL5Em.js +3599 -0
  4. package/dist/chunks/PaywallUI-CDlJL5Em.js.map +1 -0
  5. package/dist/chunks/ar-CViBaj16.js +2 -0
  6. package/dist/chunks/ar-CViBaj16.js.map +1 -0
  7. package/dist/chunks/{ar-B2Wg_IrC.js → ar-ClwBmll7.js} +5 -1
  8. package/dist/chunks/ar-ClwBmll7.js.map +1 -0
  9. package/dist/chunks/{cs-BNo9Dx0Q.js → cs-Cc_D0W4S.js} +5 -1
  10. package/dist/chunks/cs-Cc_D0W4S.js.map +1 -0
  11. package/dist/chunks/cs-DQJWP65K.js +2 -0
  12. package/dist/chunks/cs-DQJWP65K.js.map +1 -0
  13. package/dist/chunks/{da-Do9Lq6En.js → da-BtKcMSxH.js} +5 -1
  14. package/dist/chunks/da-BtKcMSxH.js.map +1 -0
  15. package/dist/chunks/da-Cyr_IXhb.js +2 -0
  16. package/dist/chunks/da-Cyr_IXhb.js.map +1 -0
  17. package/dist/chunks/de-BOCUj1pF.js +2 -0
  18. package/dist/chunks/de-BOCUj1pF.js.map +1 -0
  19. package/dist/chunks/{de-C8pDZNvx.js → de-iwQW5eYl.js} +5 -1
  20. package/dist/chunks/de-iwQW5eYl.js.map +1 -0
  21. package/dist/chunks/{el-DzMNX-_P.js → el-BoH65CeJ.js} +5 -1
  22. package/dist/chunks/el-BoH65CeJ.js.map +1 -0
  23. package/dist/chunks/el-C6jLHiEF.js +2 -0
  24. package/dist/chunks/el-C6jLHiEF.js.map +1 -0
  25. package/dist/chunks/es-CARHLxHR.js +2 -0
  26. package/dist/chunks/es-CARHLxHR.js.map +1 -0
  27. package/dist/chunks/{es-YrKt-q4w.js → es-CkP16_8K.js} +5 -1
  28. package/dist/chunks/es-CkP16_8K.js.map +1 -0
  29. package/dist/chunks/fi-B8OhRbwY.js +2 -0
  30. package/dist/chunks/fi-B8OhRbwY.js.map +1 -0
  31. package/dist/chunks/{fi-Bh44pwZ4.js → fi-yUXSmK1E.js} +5 -1
  32. package/dist/chunks/fi-yUXSmK1E.js.map +1 -0
  33. package/dist/chunks/{fr-BhYf-iKk.js → fr-CoM18zzM.js} +2 -2
  34. package/dist/chunks/fr-CoM18zzM.js.map +1 -0
  35. package/dist/chunks/{fr-Bc0pw4ws.js → fr-DSZRGsxI.js} +5 -1
  36. package/dist/chunks/fr-DSZRGsxI.js.map +1 -0
  37. package/dist/chunks/he-DTDVc3lA.js +2 -0
  38. package/dist/chunks/he-DTDVc3lA.js.map +1 -0
  39. package/dist/chunks/{he-Bfm-bhe3.js → he-ZUo7cQjk.js} +7 -3
  40. package/dist/chunks/he-ZUo7cQjk.js.map +1 -0
  41. package/dist/chunks/hi-BjnS9UeE.js +2 -0
  42. package/dist/chunks/hi-BjnS9UeE.js.map +1 -0
  43. package/dist/chunks/{hi-D-O-B9Dn.js → hi-CEutBKiG.js} +5 -1
  44. package/dist/chunks/hi-CEutBKiG.js.map +1 -0
  45. package/dist/chunks/hu-CN06FMhV.js +2 -0
  46. package/dist/chunks/hu-CN06FMhV.js.map +1 -0
  47. package/dist/chunks/{hu-CmIuAbLL.js → hu-DvEAWGS7.js} +5 -1
  48. package/dist/chunks/hu-DvEAWGS7.js.map +1 -0
  49. package/dist/chunks/id-BITgaBxq.js +2 -0
  50. package/dist/chunks/id-BITgaBxq.js.map +1 -0
  51. package/dist/chunks/{id-DN7IES-A.js → id-_eEMrYMW.js} +5 -1
  52. package/dist/chunks/id-_eEMrYMW.js.map +1 -0
  53. package/dist/chunks/index-CLB1AgLg.js +2074 -0
  54. package/dist/chunks/index-CLB1AgLg.js.map +1 -0
  55. package/dist/chunks/index-CzDSBl4d.js +2 -0
  56. package/dist/chunks/index-CzDSBl4d.js.map +1 -0
  57. package/dist/chunks/{it-Cz5Nmqx5.js → it-BAmsQbIl.js} +5 -1
  58. package/dist/chunks/it-BAmsQbIl.js.map +1 -0
  59. package/dist/chunks/it-DVcsq015.js +2 -0
  60. package/dist/chunks/it-DVcsq015.js.map +1 -0
  61. package/dist/chunks/ja-Bim7Ok2e.js +2 -0
  62. package/dist/chunks/ja-Bim7Ok2e.js.map +1 -0
  63. package/dist/chunks/{ja-BH9BlBh2.js → ja-BqCZWVKK.js} +7 -3
  64. package/dist/chunks/ja-BqCZWVKK.js.map +1 -0
  65. package/dist/chunks/{ko-CYV9QuYs.js → ko-CkIzeOzb.js} +7 -3
  66. package/dist/chunks/ko-CkIzeOzb.js.map +1 -0
  67. package/dist/chunks/ko-DqEfcVCB.js +2 -0
  68. package/dist/chunks/ko-DqEfcVCB.js.map +1 -0
  69. package/dist/chunks/nl-DSNuJWIo.js +2 -0
  70. package/dist/chunks/nl-DSNuJWIo.js.map +1 -0
  71. package/dist/chunks/{nl-BvkB900D.js → nl-Mu_KNzli.js} +5 -1
  72. package/dist/chunks/nl-Mu_KNzli.js.map +1 -0
  73. package/dist/chunks/{no-3s9_ormb.js → no-9HMjljBs.js} +5 -1
  74. package/dist/chunks/no-9HMjljBs.js.map +1 -0
  75. package/dist/chunks/no-B5HY_A8_.js +2 -0
  76. package/dist/chunks/no-B5HY_A8_.js.map +1 -0
  77. package/dist/chunks/{pl-C9WTGQtb.js → pl-Cbr2qDwv.js} +5 -1
  78. package/dist/chunks/pl-Cbr2qDwv.js.map +1 -0
  79. package/dist/chunks/pl-ChGLn9Sy.js +2 -0
  80. package/dist/chunks/pl-ChGLn9Sy.js.map +1 -0
  81. package/dist/chunks/pt-CDLEktT9.js +2 -0
  82. package/dist/chunks/pt-CDLEktT9.js.map +1 -0
  83. package/dist/chunks/{pt-uFVUv_Op.js → pt-_jirA6IR.js} +5 -1
  84. package/dist/chunks/pt-_jirA6IR.js.map +1 -0
  85. package/dist/chunks/ro-BHCHiXY3.js +2 -0
  86. package/dist/chunks/ro-BHCHiXY3.js.map +1 -0
  87. package/dist/chunks/{ro-BrqQ8Au-.js → ro-oZLxhwHc.js} +5 -1
  88. package/dist/chunks/ro-oZLxhwHc.js.map +1 -0
  89. package/dist/chunks/ru-B6HgmINj.js +2 -0
  90. package/dist/chunks/ru-B6HgmINj.js.map +1 -0
  91. package/dist/chunks/{ru-DK594dA8.js → ru-C2-sqY7B.js} +5 -1
  92. package/dist/chunks/ru-C2-sqY7B.js.map +1 -0
  93. package/dist/chunks/sv-DoSs4a9n.js +2 -0
  94. package/dist/chunks/sv-DoSs4a9n.js.map +1 -0
  95. package/dist/chunks/{sv-CHNH8-mq.js → sv-y385MWVy.js} +5 -1
  96. package/dist/chunks/sv-y385MWVy.js.map +1 -0
  97. package/dist/chunks/{th-l24Pm5q-.js → th-Bjbv4M1s.js} +5 -1
  98. package/dist/chunks/th-Bjbv4M1s.js.map +1 -0
  99. package/dist/chunks/th-UeweOhwg.js +2 -0
  100. package/dist/chunks/th-UeweOhwg.js.map +1 -0
  101. package/dist/chunks/tr-BbBr5tyB.js +2 -0
  102. package/dist/chunks/tr-BbBr5tyB.js.map +1 -0
  103. package/dist/chunks/{tr-ADpigSY5.js → tr-DmHo9F8i.js} +7 -3
  104. package/dist/chunks/tr-DmHo9F8i.js.map +1 -0
  105. package/dist/chunks/uk-CJTA1SJK.js +2 -0
  106. package/dist/chunks/uk-CJTA1SJK.js.map +1 -0
  107. package/dist/chunks/{uk-CGqo4jek.js → uk-DwvAoTe5.js} +5 -1
  108. package/dist/chunks/uk-DwvAoTe5.js.map +1 -0
  109. package/dist/chunks/{vi-Dk9bTu6f.js → vi-BEpwsVLR.js} +5 -1
  110. package/dist/chunks/vi-BEpwsVLR.js.map +1 -0
  111. package/dist/chunks/vi-ZvBo7PbB.js +2 -0
  112. package/dist/chunks/vi-ZvBo7PbB.js.map +1 -0
  113. package/dist/chunks/zh-CPZBEb3d.js +2 -0
  114. package/dist/chunks/zh-CPZBEb3d.js.map +1 -0
  115. package/dist/chunks/{zh-LDkEV2D9.js → zh-DrG18oGe.js} +7 -3
  116. package/dist/chunks/zh-DrG18oGe.js.map +1 -0
  117. package/dist/core.cjs +1 -1
  118. package/dist/core.cjs.map +1 -1
  119. package/dist/core.d.ts +89 -4
  120. package/dist/core.js +17 -2004
  121. package/dist/core.js.map +1 -1
  122. package/dist/index.cjs +1 -1
  123. package/dist/index.d.ts +188 -5
  124. package/dist/index.js +17 -13
  125. package/dist/ui.cjs +1 -1
  126. package/dist/ui.d.ts +153 -4
  127. package/dist/ui.js +1 -1
  128. package/package.json +1 -1
  129. package/dist/chunks/PaywallUI-BhQpWSWN.js +0 -3224
  130. package/dist/chunks/PaywallUI-BhQpWSWN.js.map +0 -1
  131. package/dist/chunks/PaywallUI-C7Wp2TiR.js +0 -26
  132. package/dist/chunks/PaywallUI-C7Wp2TiR.js.map +0 -1
  133. package/dist/chunks/ar-7cgIM-Vl.js +0 -2
  134. package/dist/chunks/ar-7cgIM-Vl.js.map +0 -1
  135. package/dist/chunks/ar-B2Wg_IrC.js.map +0 -1
  136. package/dist/chunks/cs-BNo9Dx0Q.js.map +0 -1
  137. package/dist/chunks/cs-S05PC5AC.js +0 -2
  138. package/dist/chunks/cs-S05PC5AC.js.map +0 -1
  139. package/dist/chunks/da-Bi4zBG14.js +0 -2
  140. package/dist/chunks/da-Bi4zBG14.js.map +0 -1
  141. package/dist/chunks/da-Do9Lq6En.js.map +0 -1
  142. package/dist/chunks/de-C8pDZNvx.js.map +0 -1
  143. package/dist/chunks/de-nCDB6D2W.js +0 -2
  144. package/dist/chunks/de-nCDB6D2W.js.map +0 -1
  145. package/dist/chunks/el-BrKaa978.js +0 -2
  146. package/dist/chunks/el-BrKaa978.js.map +0 -1
  147. package/dist/chunks/el-DzMNX-_P.js.map +0 -1
  148. package/dist/chunks/es-B-Wtyzrl.js +0 -2
  149. package/dist/chunks/es-B-Wtyzrl.js.map +0 -1
  150. package/dist/chunks/es-YrKt-q4w.js.map +0 -1
  151. package/dist/chunks/fi-Bh44pwZ4.js.map +0 -1
  152. package/dist/chunks/fi-D1SGXjnO.js +0 -2
  153. package/dist/chunks/fi-D1SGXjnO.js.map +0 -1
  154. package/dist/chunks/fr-Bc0pw4ws.js.map +0 -1
  155. package/dist/chunks/fr-BhYf-iKk.js.map +0 -1
  156. package/dist/chunks/he-BXAaFv6Y.js +0 -2
  157. package/dist/chunks/he-BXAaFv6Y.js.map +0 -1
  158. package/dist/chunks/he-Bfm-bhe3.js.map +0 -1
  159. package/dist/chunks/hi-D-O-B9Dn.js.map +0 -1
  160. package/dist/chunks/hi-xblDO0O7.js +0 -2
  161. package/dist/chunks/hi-xblDO0O7.js.map +0 -1
  162. package/dist/chunks/hu-CmIuAbLL.js.map +0 -1
  163. package/dist/chunks/hu-Wa46p0y4.js +0 -2
  164. package/dist/chunks/hu-Wa46p0y4.js.map +0 -1
  165. package/dist/chunks/id-CQEo5X94.js +0 -2
  166. package/dist/chunks/id-CQEo5X94.js.map +0 -1
  167. package/dist/chunks/id-DN7IES-A.js.map +0 -1
  168. package/dist/chunks/it-8AYCm0xz.js +0 -2
  169. package/dist/chunks/it-8AYCm0xz.js.map +0 -1
  170. package/dist/chunks/it-Cz5Nmqx5.js.map +0 -1
  171. package/dist/chunks/ja-BH9BlBh2.js.map +0 -1
  172. package/dist/chunks/ja-q-COVayn.js +0 -2
  173. package/dist/chunks/ja-q-COVayn.js.map +0 -1
  174. package/dist/chunks/ko-B6HRCscZ.js +0 -2
  175. package/dist/chunks/ko-B6HRCscZ.js.map +0 -1
  176. package/dist/chunks/ko-CYV9QuYs.js.map +0 -1
  177. package/dist/chunks/nl-BvkB900D.js.map +0 -1
  178. package/dist/chunks/nl-CAd6_xlm.js +0 -2
  179. package/dist/chunks/nl-CAd6_xlm.js.map +0 -1
  180. package/dist/chunks/no-3s9_ormb.js.map +0 -1
  181. package/dist/chunks/no-CAmz6bz6.js +0 -2
  182. package/dist/chunks/no-CAmz6bz6.js.map +0 -1
  183. package/dist/chunks/pl-C9WTGQtb.js.map +0 -1
  184. package/dist/chunks/pl-DqUSTCaF.js +0 -2
  185. package/dist/chunks/pl-DqUSTCaF.js.map +0 -1
  186. package/dist/chunks/pt-8ARZnH0_.js +0 -2
  187. package/dist/chunks/pt-8ARZnH0_.js.map +0 -1
  188. package/dist/chunks/pt-uFVUv_Op.js.map +0 -1
  189. package/dist/chunks/ro-BrqQ8Au-.js.map +0 -1
  190. package/dist/chunks/ro-D-NMbp2F.js +0 -2
  191. package/dist/chunks/ro-D-NMbp2F.js.map +0 -1
  192. package/dist/chunks/ru-8gbHPh0g.js +0 -2
  193. package/dist/chunks/ru-8gbHPh0g.js.map +0 -1
  194. package/dist/chunks/ru-DK594dA8.js.map +0 -1
  195. package/dist/chunks/sv-CHNH8-mq.js.map +0 -1
  196. package/dist/chunks/sv-D8a8hmx9.js +0 -2
  197. package/dist/chunks/sv-D8a8hmx9.js.map +0 -1
  198. package/dist/chunks/th-DfjUK0Y7.js +0 -2
  199. package/dist/chunks/th-DfjUK0Y7.js.map +0 -1
  200. package/dist/chunks/th-l24Pm5q-.js.map +0 -1
  201. package/dist/chunks/tr-ADpigSY5.js.map +0 -1
  202. package/dist/chunks/tr-BdBpz4tL.js +0 -2
  203. package/dist/chunks/tr-BdBpz4tL.js.map +0 -1
  204. package/dist/chunks/uk-CGqo4jek.js.map +0 -1
  205. package/dist/chunks/uk-Cx1zv1ao.js +0 -2
  206. package/dist/chunks/uk-Cx1zv1ao.js.map +0 -1
  207. package/dist/chunks/vi-Dk9bTu6f.js.map +0 -1
  208. package/dist/chunks/vi-oe2dW21I.js +0 -2
  209. package/dist/chunks/vi-oe2dW21I.js.map +0 -1
  210. package/dist/chunks/zh-CwczPMPp.js +0 -2
  211. package/dist/chunks/zh-CwczPMPp.js.map +0 -1
  212. package/dist/chunks/zh-LDkEV2D9.js.map +0 -1
package/dist/core.d.ts CHANGED
@@ -610,6 +610,13 @@ export declare class BillingClient {
610
610
  }): Promise<PaywallPrice[]>;
611
611
  /** Sync-снимок цен из последнего bootstrap'а. null = ещё не загружали. */
612
612
  getCachedPrices(): PaywallPrice[] | null;
613
+ /** Sync-снимок офферов из последнего bootstrap'а. null = bootstrap ещё не
614
+ * загружали, пустой массив = бэк отдал пейвол без офферов. Бэк уже
615
+ * применил серверный таргетинг (target_countries / target_emails /
616
+ * targeting_mode из offer_settings) — наружу выезжает только то, что
617
+ * применимо к текущему юзеру. Клиентская сторона остаётся ответственной
618
+ * за price_id-matching и countdown (см. core/offer.ts → resolveOffer). */
619
+ getCachedOffers(): PaywallOffer[] | null;
613
620
  /**
614
621
  * Снимок того, какой язык SDK сейчас считает «языком юзера». Полезно для
615
622
  * синхронизации i18n хоста с тем, что фактически показывает пейвол — чтобы
@@ -736,6 +743,17 @@ export declare class BillingClient {
736
743
  errorUrl?: string;
737
744
  shopUrl?: string;
738
745
  trialDays?: number;
746
+ /** Активный offer для этой цены — резолвится host'ом через
747
+ * `paywall.getOfferForPrice(priceId)?.offer.id` или
748
+ * `findApplicableOffer(client.getCachedOffers(), priceId)?.id`. Без
749
+ * явной передачи бэк сделает auto-resolve по email — но только для
750
+ * end_date-офферов. duration_minutes-офферы тикают в clientStorage и
751
+ * сервер их не видит: для них offerId ОБЯЗАН прийти от клиента, иначе
752
+ * скидка не применится на чекауте, хотя UI её показывал.
753
+ *
754
+ * Передавать offer-id всегда безопасно — бэк сам проверит applicable
755
+ * ли offer к этому юзеру (страна/email/режим) и игнорирует если нет. */
756
+ offerId?: string;
739
757
  /**
740
758
  * Stage 1 защиты от дубликатов покупок. Идемпотентный ключ запроса
741
759
  * (UUID). Повторный вызов с тем же ключом вернёт тот же checkout-URL
@@ -762,7 +780,9 @@ export declare class BillingClient {
762
780
  * инвойсы). Опен-флоу управляется host'ом:
763
781
  *
764
782
  * ```ts
765
- * const { url } = await billing.getCustomerPortalUrl();
783
+ * const { url } = await billing.getCustomerPortalUrl({
784
+ * returnUrl: 'https://your-app.com/account'
785
+ * });
766
786
  * window.open(url, '_blank');
767
787
  * ```
768
788
  *
@@ -774,6 +794,14 @@ export declare class BillingClient {
774
794
  */
775
795
  getCustomerPortalUrl(opts?: {
776
796
  signal?: AbortSignal;
797
+ /** URL для return-button у провайдера (Stripe «Return to ...», Paddle
798
+ * и Chargebee redirect_url'ы). Передавай туда страницу-аккаунт твоего
799
+ * app'а — `https://your-app.com/account`. Без явного returnUrl бэк
800
+ * применяет fallback в порядке: `paywall_settings.shop_url` →
801
+ * custom_domain пейвола → NEXT_PUBLIC_ONLINE_ORIGIN (последнее — это
802
+ * страница в самом online-сервисе, годится только для legacy
803
+ * v2-iframe-флоу). */
804
+ returnUrl?: string;
777
805
  }): Promise<{
778
806
  url: string;
779
807
  }>;
@@ -939,6 +967,11 @@ export declare interface EventTrackerOptions {
939
967
  sendBeacon?: (url: string, data: BodyInit) => boolean;
940
968
  }
941
969
 
970
+ /** Pick the offer applicable to a price. Targeted (`price_id === id`) wins
971
+ * over the global default (`price_id === null`). Offers without a positive
972
+ * `discount_percent` are ignored. */
973
+ export declare function findApplicableOffer(offers: PaywallOffer[] | null | undefined, priceId: string): PaywallOffer | null;
974
+
942
975
  export declare function generateVisitorId(): string;
943
976
 
944
977
  export declare interface Identity {
@@ -1099,6 +1132,11 @@ export declare interface LocaleOverrides {
1099
1132
 
1100
1133
  export declare type OAuthProvider = 'google' | 'apple' | 'github' | 'facebook';
1101
1134
 
1135
+ /** Storage key under which a relative `duration_minutes` offer records its
1136
+ * first-view timestamp. Shared between the renderer (which writes the
1137
+ * start on first open) and the host SDK helpers (which read it). */
1138
+ export declare function offerStartStorageKey(offerId: string): string;
1139
+
1102
1140
  export declare type OtpVerifyType = 'email' | 'recovery' | 'signup' | 'magiclink' | 'invite';
1103
1141
 
1104
1142
  export declare interface PaywallBootstrap {
@@ -1139,8 +1177,10 @@ export declare interface PaywallOffer {
1139
1177
  expires_at: string | null;
1140
1178
  /** Относительный таймер: сколько минут offer живёт **от первого просмотра
1141
1179
  * пейвола** данным юзером. Старт хранится в clientStorage под ключом
1142
- * `pw-offer-{id}-start`, по истечении auto-cleanup. Используется, когда
1143
- * бэк хочет показывать "remaining time" без жёсткой server-time, а считать
1180
+ * `pw-offer-{id}-start` и остаётся там **после** expiry — это
1181
+ * forever-marker, чтобы юзер не мог «фармить» offer (re-open пейвола
1182
+ * не запускает countdown заново). Используется, когда бэк хочет
1183
+ * показывать "remaining time" без жёсткой server-time, а считать
1144
1184
  * относительно сессии юзера. expires_at имеет приоритет если задано. */
1145
1185
  duration_minutes?: number | null;
1146
1186
  price_id: string | null;
@@ -1167,7 +1207,7 @@ export declare interface PaywallPrice {
1167
1207
  * идёт из `/user-state` и имеет минимум для access-gate'а), этот shape
1168
1208
  * включает цену/валюту/discount — чтобы host мог нарисовать список подписок
1169
1209
  * как в legacy customer portal'е. */
1170
- declare interface PaywallPurchaseDetailed {
1210
+ export declare interface PaywallPurchaseDetailed {
1171
1211
  id: string;
1172
1212
  status: string | null;
1173
1213
  cancel_at: string | null;
@@ -1287,6 +1327,51 @@ export declare class QuotaExceededError extends PaywallError {
1287
1327
  });
1288
1328
  }
1289
1329
 
1330
+ /** Safe browser localStorage getter — returns null in SSR / private mode. */
1331
+ export declare function readBrowserOfferStart(offerId: string): string | null;
1332
+
1333
+ /**
1334
+ * Resolved view of a paywall offer — what host UI actually needs to render
1335
+ * a strike-through price + countdown without re-implementing the math.
1336
+ *
1337
+ * `remainingMs` ticks down with wall-clock time and reaches 0 on expiry.
1338
+ * `totalMs` stays constant — useful for progress bars / share-of-time UX.
1339
+ * `expiresAt` is the Date.now()-comparable epoch ms of expiry.
1340
+ *
1341
+ * For offers without an expiry mechanism (no `expires_at` and no
1342
+ * `duration_minutes`), `remainingMs`/`totalMs`/`expiresAt` are all `null`,
1343
+ * but the resolved view is still returned — discount badge / strike-through
1344
+ * still make sense for "perpetual sale" offers.
1345
+ */
1346
+ export declare interface ResolvedOffer {
1347
+ offer: PaywallOffer;
1348
+ discountPercent: number;
1349
+ remainingMs: number | null;
1350
+ totalMs: number | null;
1351
+ expiresAt: number | null;
1352
+ }
1353
+
1354
+ /** Compute the resolved view of an offer. Pure, no side-effects. */
1355
+ export declare function resolveOffer(offer: PaywallOffer, opts?: ResolveOfferOptions): ResolvedOffer | null;
1356
+
1357
+ export declare interface ResolveOfferOptions {
1358
+ /** Current epoch ms. Inject for deterministic tests; default `Date.now()`. */
1359
+ now?: number;
1360
+ /**
1361
+ * Synchronous reader for the `duration_minutes` start-timestamp ISO string.
1362
+ * Host passes a closure over its sync storage (browser → `localStorage`,
1363
+ * memory → in-process map). Return `null` if no start has been recorded.
1364
+ *
1365
+ * Intentionally synchronous, because consumers call this from UI render —
1366
+ * an async StorageAdapter would force every price card to suspend.
1367
+ *
1368
+ * If omitted, `duration_minutes`-only offers return `expiresAt = null`,
1369
+ * which makes the resolved view treat them as "not yet started" (the
1370
+ * renderer is responsible for writing the start on first paywall view).
1371
+ */
1372
+ readStart?: (offerId: string) => string | null;
1373
+ }
1374
+
1290
1375
  export declare const SDK_VERSION = "3.0.0-alpha.0";
1291
1376
 
1292
1377
  export declare type SignUpResult = {