@monetize.software/sdk-extension 3.0.0-alpha.3 → 3.0.0-alpha.4

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.
@@ -3,7 +3,7 @@ class o extends Error {
3
3
  super(e), this.name = "PaywallError", this.code = t, this.status = s.status, this.cause = s.cause;
4
4
  }
5
5
  }
6
- class N extends o {
6
+ class q extends o {
7
7
  constructor(t) {
8
8
  super("not_enough_queries", t.message ?? "Not enough queries", {
9
9
  status: 402
@@ -11,7 +11,7 @@ class N extends o {
11
11
  }
12
12
  }
13
13
  const m = "3.0.0-alpha.0";
14
- class P {
14
+ class L {
15
15
  constructor(t) {
16
16
  this.opts = t;
17
17
  }
@@ -34,13 +34,13 @@ class P {
34
34
  }
35
35
  const f = (u.headers.get("content-type") ?? "").includes("application/json") ? await u.json().catch(() => null) : null;
36
36
  if (!u.ok) {
37
- const h = f && typeof f == "object" && "code" in f && String(f.code) || `http_${u.status}`, g = f && typeof f == "object" && "message" in f && String(f.message) || u.statusText || "Request failed";
38
- throw new o(h, g, { status: u.status, cause: f });
37
+ const h = f && typeof f == "object" && "code" in f && String(f.code) || `http_${u.status}`, w = f && typeof f == "object" && "message" in f && String(f.message) || u.statusText || "Request failed";
38
+ throw new o(h, w, { status: u.status, cause: f });
39
39
  }
40
40
  return f;
41
41
  }
42
42
  }
43
- function D() {
43
+ function $() {
44
44
  return typeof chrome < "u" && !!chrome?.storage?.local && !!chrome?.runtime?.id;
45
45
  }
46
46
  const x = {
@@ -73,7 +73,7 @@ const x = {
73
73
  };
74
74
  return e.addListener(s), () => e.removeListener(s);
75
75
  }
76
- }, J = {
76
+ }, H = {
77
77
  async getItem(i) {
78
78
  try {
79
79
  return window.localStorage.getItem(i);
@@ -101,19 +101,19 @@ const x = {
101
101
  };
102
102
  return window.addEventListener("storage", e), () => window.removeEventListener("storage", e);
103
103
  }
104
- }, b = /* @__PURE__ */ new Map(), H = {
104
+ }, I = /* @__PURE__ */ new Map(), J = {
105
105
  async getItem(i) {
106
- return b.get(i) ?? null;
106
+ return I.get(i) ?? null;
107
107
  },
108
108
  async setItem(i, t) {
109
- b.set(i, t);
109
+ I.set(i, t);
110
110
  },
111
111
  async removeItem(i) {
112
- b.delete(i);
112
+ I.delete(i);
113
113
  }
114
114
  };
115
115
  function R(i) {
116
- return i || (D() ? x : typeof window < "u" && "localStorage" in window ? J : H);
116
+ return i || ($() ? x : typeof window < "u" && "localStorage" in window ? H : J);
117
117
  }
118
118
  const y = {
119
119
  visitorId: "pw-visitor-id",
@@ -145,7 +145,7 @@ const y = {
145
145
  // (оптимистично через `decrementBalanceLocal`).
146
146
  balances: (i, t) => `pw-${i}-${t}-balances-v1`
147
147
  };
148
- function M() {
148
+ function P() {
149
149
  const i = typeof globalThis < "u" ? globalThis.crypto : void 0;
150
150
  if (i && typeof i.randomUUID == "function") return i.randomUUID();
151
151
  const t = new Uint8Array(16);
@@ -157,20 +157,20 @@ function M() {
157
157
  const e = Array.from(t, (s) => s.toString(16).padStart(2, "0")).join("");
158
158
  return `${e.slice(0, 8)}-${e.slice(8, 12)}-${e.slice(12, 16)}-${e.slice(16, 20)}-${e.slice(20)}`;
159
159
  }
160
- async function B(i) {
160
+ async function _(i) {
161
161
  try {
162
162
  const e = await i.getItem(y.visitorId);
163
163
  if (e && typeof e == "string" && e.length >= 16) return e;
164
164
  } catch {
165
165
  }
166
- const t = M();
166
+ const t = P();
167
167
  try {
168
168
  await i.setItem(y.visitorId, t);
169
169
  } catch {
170
170
  }
171
171
  return t;
172
172
  }
173
- function q(i) {
173
+ function D(i) {
174
174
  const t = new Uint8Array(i), e = typeof globalThis < "u" ? globalThis.crypto : void 0;
175
175
  if (e && typeof e.getRandomValues == "function")
176
176
  e.getRandomValues(t);
@@ -178,30 +178,30 @@ function q(i) {
178
178
  for (let s = 0; s < i; s++) t[s] = Math.floor(Math.random() * 256);
179
179
  return t;
180
180
  }
181
- function I(i) {
181
+ function b(i) {
182
182
  let t = "";
183
183
  for (let e = 0; e < i.length; e++) t += String.fromCharCode(i[e]);
184
184
  return btoa(t).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
185
185
  }
186
186
  function V() {
187
- return I(q(64));
187
+ return b(D(64));
188
188
  }
189
189
  async function j(i) {
190
190
  const t = new TextEncoder().encode(i), e = globalThis.crypto;
191
191
  if (!e?.subtle?.digest)
192
192
  throw new Error("crypto.subtle is required for PKCE");
193
193
  const s = await e.subtle.digest("SHA-256", t);
194
- return I(new Uint8Array(s));
194
+ return b(new Uint8Array(s));
195
195
  }
196
- function X() {
197
- return I(q(16));
196
+ function G() {
197
+ return b(D(16));
198
198
  }
199
- const z = "https://appbox.space", G = 6e4, Q = 600 * 1e3;
199
+ const X = "https://appbox.space", z = 6e4, Q = 600 * 1e3;
200
200
  class mt {
201
201
  constructor(t) {
202
202
  if (this.session = null, this.inflightRefresh = null, this.inflightAnonSignin = null, this.listeners = /* @__PURE__ */ new Set(), this.storageUnwatch = null, this.destroyed = !1, this.oauthFlows = /* @__PURE__ */ new Map(), !t.paywallId)
203
203
  throw new o("invalid_config", "paywallId is required");
204
- this.paywallId = t.paywallId, this.apiOrigin = t.apiOrigin ?? z, this.storage = R(t.storage), this.api = new P({
204
+ this.paywallId = t.paywallId, this.apiOrigin = t.apiOrigin ?? X, this.storage = R(t.storage), this.api = new L({
205
205
  apiOrigin: this.apiOrigin,
206
206
  paywallId: t.paywallId,
207
207
  fetch: t.fetch
@@ -227,14 +227,15 @@ class mt {
227
227
  async applyExternalSession(t) {
228
228
  if (!this.destroyed && (await this.hydrated, !this.destroyed)) {
229
229
  if (t == null) {
230
- this.session && this.setSession(null, { skipPersist: !0 });
230
+ this.session && this.setSession(null, { skipPersist: !0, event: "SIGNED_OUT" });
231
231
  return;
232
232
  }
233
233
  try {
234
234
  const e = JSON.parse(t);
235
235
  if (!e || typeof e.access_token != "string" || typeof e.refresh_token != "string" || typeof e.expires_at != "number" || !e.user)
236
236
  return;
237
- this.setSession(e, { skipPersist: !0 });
237
+ const s = !this.session || this.session.user.id !== e.user.id ? "SIGNED_IN" : "TOKEN_REFRESHED";
238
+ this.setSession(e, { skipPersist: !0, event: s });
238
239
  } catch {
239
240
  }
240
241
  }
@@ -291,7 +292,7 @@ class mt {
291
292
  })
292
293
  }
293
294
  ), n = this.toSession(a, a.user);
294
- return this.setSession(n), n;
295
+ return this.setSession(n, { event: "SIGNED_IN" }), n;
295
296
  }
296
297
  /**
297
298
  * Signup. Если в Supabase включён email confirm — сервер возвращает
@@ -319,7 +320,7 @@ class mt {
319
320
  if (a.status === "confirmation_required")
320
321
  return { kind: "confirmation_required", user: a.user };
321
322
  const n = this.toSession(a, a.user);
322
- return this.setSession(n), { kind: "signed_in", session: n };
323
+ return this.setSession(n, { event: "SIGNED_IN" }), { kind: "signed_in", session: n };
323
324
  }
324
325
  /**
325
326
  * Повторная отправка confirmation-email после signUp с включённым
@@ -382,8 +383,8 @@ class mt {
382
383
  user_meta: t.userMeta
383
384
  })
384
385
  }
385
- ), a = this.toSession(s, s.user);
386
- return this.setSession(a), a;
386
+ ), a = this.toSession(s, s.user), n = t.type === "recovery" ? "PASSWORD_RECOVERY" : "SIGNED_IN";
387
+ return this.setSession(a, { event: n }), a;
387
388
  }
388
389
  /**
389
390
  * Запрос recovery email. Бэк всегда ok, чтобы не палить enumeration.
@@ -475,7 +476,7 @@ class mt {
475
476
  email: s.user.email ?? null,
476
477
  is_anonymous: !0
477
478
  }, n = this.toSession(s, a);
478
- return this.setSession(n), await this.writeAnonRefreshToken(n.refresh_token), n;
479
+ return this.setSession(n, { event: "SIGNED_IN" }), await this.writeAnonRefreshToken(n.refresh_token), n;
479
480
  })();
480
481
  try {
481
482
  return await this.inflightAnonSignin;
@@ -497,7 +498,7 @@ class mt {
497
498
  `/api/v1/paywall/${this.paywallId}/auth/refresh`,
498
499
  { method: "POST", body: JSON.stringify({ refresh_token: t }) }
499
500
  ), s = this.session?.user.is_anonymous === !0 ? this.session.user : { id: "", email: null, is_anonymous: !0 }, a = this.toSession(e, s);
500
- return this.setSession(a), await this.writeAnonRefreshToken(a.refresh_token), a;
501
+ return this.setSession(a, { event: "SIGNED_IN" }), await this.writeAnonRefreshToken(a.refresh_token), a;
501
502
  } catch (e) {
502
503
  if (e instanceof o && e.status === 401)
503
504
  return await this.clearAnonRefreshToken(), null;
@@ -560,7 +561,7 @@ class mt {
560
561
  email: a.user.email,
561
562
  is_anonymous: a.user.is_anonymous ?? !1
562
563
  }, l = { ...n, user: r };
563
- return this.setSession(l), await this.clearAnonRefreshToken(), { kind: "updated", session: l };
564
+ return this.setSession(l, { event: "USER_UPDATED" }), await this.clearAnonRefreshToken(), { kind: "updated", session: l };
564
565
  }
565
566
  /**
566
567
  * OAuth signin через popup с PKCE. Жизненный цикл:
@@ -617,7 +618,7 @@ class mt {
617
618
  */
618
619
  async startOAuthFlow(t) {
619
620
  await this.hydrated, this.gcOAuthFlows();
620
- const e = V(), s = await j(e), a = X(), n = {}, r = await this.getAccessToken().catch(() => null);
621
+ const e = V(), s = await j(e), a = G(), n = {}, r = await this.getAccessToken().catch(() => null);
621
622
  r && (n.Authorization = `Bearer ${r}`);
622
623
  const { authorize_url: l } = await this.api.request(
623
624
  `/api/v1/paywall/${this.paywallId}/auth/oauth/init`,
@@ -671,7 +672,7 @@ class mt {
671
672
  if (this.destroyed)
672
673
  throw new o("aborted", "AuthClient destroyed mid-flow");
673
674
  const n = this.toSession(a, a.user);
674
- return this.setSession(n), n;
675
+ return this.setSession(n, { event: "SIGNED_IN" }), n;
675
676
  }
676
677
  gcOAuthFlows() {
677
678
  const t = Date.now() - Q;
@@ -700,10 +701,10 @@ class mt {
700
701
  body: JSON.stringify({ refresh_token: t })
701
702
  }
702
703
  ), a = this.toSession(s, e);
703
- return this.setSession(a), e.is_anonymous === !0 && await this.writeAnonRefreshToken(a.refresh_token), a;
704
+ return this.setSession(a, { event: "TOKEN_REFRESHED" }), e.is_anonymous === !0 && await this.writeAnonRefreshToken(a.refresh_token), a;
704
705
  } catch (s) {
705
706
  if (s instanceof o && s.status === 401)
706
- return e.is_anonymous === !0 && await this.clearAnonRefreshToken(), this.setSession(null), null;
707
+ return e.is_anonymous === !0 && await this.clearAnonRefreshToken(), this.setSession(null, { event: "SIGNED_OUT" }), null;
707
708
  throw s;
708
709
  } finally {
709
710
  this.inflightRefresh = null;
@@ -736,7 +737,7 @@ class mt {
736
737
  method: "POST",
737
738
  headers: { Authorization: `Bearer ${t}` }
738
739
  }
739
- ), this.setSession(null);
740
+ ), this.setSession(null, { event: "SIGNED_OUT" });
740
741
  }
741
742
  /**
742
743
  * Signout: чистит локальную session СРАЗУ (UX — мгновенный logout без
@@ -756,7 +757,7 @@ class mt {
756
757
  async signOut(t = {}) {
757
758
  await this.hydrated;
758
759
  const e = this.session?.access_token, s = this.session?.user.is_anonymous === !0;
759
- if (this.setSession(null), t.forgetAnonymous && await this.clearAnonRefreshToken(), !!e && !(s && !t.forgetAnonymous))
760
+ if (this.setSession(null, { event: "SIGNED_OUT" }), t.forgetAnonymous && await this.clearAnonRefreshToken(), !!e && !(s && !t.forgetAnonymous))
760
761
  try {
761
762
  await this.api.request(
762
763
  `/api/v1/paywall/${this.paywallId}/auth/signout`,
@@ -770,22 +771,35 @@ class mt {
770
771
  }
771
772
  /**
772
773
  * Подписка на изменения session: signin/signup/refresh/signOut/expired-401.
773
- * Колбек вызывается с текущим snapshot через microtask (если session есть)
774
- * + на каждое реальное изменение. Возвращает unsubscribe.
774
+ *
775
+ * Гарантированный контракт: ПЕРВЫЙ callback каждому subscriber'у — всегда
776
+ * `event = 'INITIAL_SESSION'`, дёргается асинхронно после resolve hydrate'а
777
+ * (даже если session=null — listener получает explicit «нет сессии», а не
778
+ * молчание). Все последующие callback'и — реальные переходы с конкретным
779
+ * event'ом (SIGNED_IN / SIGNED_OUT / TOKEN_REFRESHED / USER_UPDATED /
780
+ * PASSWORD_RECOVERY).
781
+ *
782
+ * Это позволяет listener'у безопасно делать «only on real signin» побочные
783
+ * эффекты (force refetch balances и т.п.) через `event === 'SIGNED_IN'`,
784
+ * не путая их с восстановлением из storage.
785
+ *
786
+ * Возвращает unsubscribe.
775
787
  */
776
788
  onAuthChange(t) {
777
- if (this.listeners.add(t), this.session) {
789
+ return this.listeners.add(t), this.hydrated.then(() => {
790
+ if (this.destroyed || !this.listeners.has(t)) return;
778
791
  const e = this.session;
779
- queueMicrotask(() => {
780
- this.listeners.has(t) && t(e);
781
- });
782
- }
783
- return () => {
792
+ try {
793
+ t("INITIAL_SESSION", e);
794
+ } catch (s) {
795
+ console.warn("[paywall] onAuthChange INITIAL_SESSION threw", s);
796
+ }
797
+ }), () => {
784
798
  this.listeners.delete(t);
785
799
  };
786
800
  }
787
801
  isFresh(t) {
788
- return t.expires_at - Date.now() > G;
802
+ return t.expires_at - Date.now() > z;
789
803
  }
790
804
  toSession(t, e) {
791
805
  const s = t.expires_at != null ? t.expires_at * 1e3 : Date.now() + t.expires_in * 1e3;
@@ -796,17 +810,17 @@ class mt {
796
810
  user: e
797
811
  };
798
812
  }
799
- setSession(t, e = {}) {
813
+ setSession(t, e) {
800
814
  if (this.destroyed) return;
801
815
  const s = this.session;
802
- this.session = t, e.skipPersist || this.persist(), tt(s, t) || this.emit();
816
+ this.session = t, e.skipPersist || this.persist(), tt(s, t) || this.emit(e.event);
803
817
  }
804
- emit() {
805
- for (const t of this.listeners)
818
+ emit(t) {
819
+ for (const e of this.listeners)
806
820
  try {
807
- t(this.session);
808
- } catch (e) {
809
- console.warn("[paywall] onAuthChange listener threw", e);
821
+ e(t, this.session);
822
+ } catch (s) {
823
+ console.warn("[paywall] onAuthChange listener threw", s);
810
824
  }
811
825
  }
812
826
  storageKey() {
@@ -819,7 +833,7 @@ class mt {
819
833
  const e = JSON.parse(t);
820
834
  if (!e || typeof e.access_token != "string" || typeof e.refresh_token != "string" || typeof e.expires_at != "number" || !e.user)
821
835
  return;
822
- this.session = e, this.emit();
836
+ this.session = e;
823
837
  } catch {
824
838
  }
825
839
  }
@@ -833,7 +847,7 @@ class mt {
833
847
  const e = JSON.parse(t);
834
848
  if (!e || typeof e.access_token != "string" || typeof e.refresh_token != "string" || typeof e.expires_at != "number" || !e.user)
835
849
  return;
836
- this.setSession(e, { skipPersist: !0 });
850
+ this.setSession(e, { skipPersist: !0, event: "SIGNED_IN" });
837
851
  } catch {
838
852
  }
839
853
  }
@@ -1007,8 +1021,8 @@ class st {
1007
1021
  { status: h.status }
1008
1022
  );
1009
1023
  }
1010
- const g = h.headers.get("X-Query-Type") ?? void 0;
1011
- return this.onChargeSuccess?.(g), h;
1024
+ const w = h.headers.get("X-Query-Type") ?? void 0;
1025
+ return this.onChargeSuccess?.(w), h;
1012
1026
  }
1013
1027
  }
1014
1028
  async function it(i) {
@@ -1023,7 +1037,7 @@ async function it(i) {
1023
1037
  const a = e[0];
1024
1038
  Array.isArray(a) ? s = a : a && Array.isArray(a.balances) && (s = a.balances);
1025
1039
  }
1026
- return new N({
1040
+ return new q({
1027
1041
  balances: s,
1028
1042
  queryType: t.details?.queryType ?? "",
1029
1043
  currentBalance: t.details?.currentBalance ?? null
@@ -1038,12 +1052,12 @@ async function at(i) {
1038
1052
  return null;
1039
1053
  }
1040
1054
  }
1041
- const nt = 5e3, rt = 30 * 6e4, _ = 60 * 6e4, ot = 5 * 6e4, k = {
1055
+ const nt = 5e3, rt = 30 * 6e4, B = 60 * 6e4, ot = 5 * 6e4, A = {
1042
1056
  has_active_subscription: !1,
1043
1057
  purchases: [],
1044
1058
  trial: null
1045
1059
  };
1046
- function A(i) {
1060
+ function k(i) {
1047
1061
  return i && (i.email || i.userId || i.anonymousId) || "guest";
1048
1062
  }
1049
1063
  function ct(i, t) {
@@ -1058,7 +1072,7 @@ function ut(i, t) {
1058
1072
  return !0;
1059
1073
  }
1060
1074
  const dt = "https://appbox.space";
1061
- class bt {
1075
+ class It {
1062
1076
  constructor(t) {
1063
1077
  if (this.cachedBootstrap = null, this.cachedBootstrapAt = 0, this.inflightBootstrap = null, this.bootstrapListeners = /* @__PURE__ */ new Set(), this.bootstrapStorageUnwatch = null, this.authUnsubscribe = null, this.cachedUser = null, this.cachedUserAt = 0, this.inflightUser = null, this.userListeners = /* @__PURE__ */ new Set(), this.visitorIdPromise = null, this.visitorId = null, this.inflightCheckouts = /* @__PURE__ */ new Map(), this.cachedBalances = null, this.cachedBalancesAt = 0, this.balancesStorageUnwatch = null, this.inflightBalances = null, this.balanceListeners = /* @__PURE__ */ new Set(), this.previewVersionCounter = 0, !t.paywallId)
1064
1078
  throw new o("invalid_config", "paywallId is required");
@@ -1066,7 +1080,7 @@ class bt {
1066
1080
  const e = t.auth?.getCachedUser();
1067
1081
  this.identity = t.identity ?? (e ? U(e) : void 0), this.apiKey = t.apiKey, this.fetchImpl = t.fetch, t.apiKey && typeof window < "u" && typeof window.document < "u" && console.error(
1068
1082
  "[paywall] SECURITY: BillingClient.apiKey detected in browser context. This is a server-SDK key and exposes your account. Remove apiKey or move BillingClient to a trusted backend."
1069
- ), this.storage = R(t.storage), this.api = new P({
1083
+ ), this.storage = R(t.storage), this.api = new L({
1070
1084
  apiOrigin: this.apiOrigin,
1071
1085
  paywallId: t.paywallId,
1072
1086
  capabilities: t.capabilities,
@@ -1075,10 +1089,10 @@ class bt {
1075
1089
  // делает lazy refresh, дедупит, на 401 возвращает null — тогда
1076
1090
  // Authorization-хедер просто не выставится.
1077
1091
  getAuthToken: t.auth ? () => t.auth.getAccessToken() : void 0
1078
- }), t.auth && (this.authUnsubscribe = t.auth.onAuthChange((s) => {
1079
- const a = s ? U(s.user) : void 0;
1080
- ft(this.identity, a) || this.setIdentity(a);
1081
- })), this.hydrateUserFromStorage(), this.hydrateBootstrapFromStorage(), this.subscribeBootstrapStorage(), this.hydrateBalancesFromStorage(), this.subscribeBalancesStorage(), this.visitorIdPromise = B(this.storage).then((s) => (this.visitorId = s, s));
1092
+ }), t.auth && (this.authUnsubscribe = t.auth.onAuthChange((s, a) => {
1093
+ const n = a ? U(a.user) : void 0;
1094
+ ft(this.identity, n) || this.setIdentity(n);
1095
+ })), this.hydrateUserFromStorage(), this.hydrateBootstrapFromStorage(), this.subscribeBootstrapStorage(), this.hydrateBalancesFromStorage(), this.subscribeBalancesStorage(), this.visitorIdPromise = _(this.storage).then((s) => (this.visitorId = s, s));
1082
1096
  }
1083
1097
  /**
1084
1098
  * Stable visitor_id (UUID v4). Первый вызов awaitит первичный резолв из
@@ -1086,7 +1100,7 @@ class bt {
1086
1100
  * EventTracker'ом для атрибуции аналитики.
1087
1101
  */
1088
1102
  async getVisitorId() {
1089
- return this.visitorId ? this.visitorId : (this.visitorIdPromise || (this.visitorIdPromise = B(this.storage).then((t) => (this.visitorId = t, t))), this.visitorIdPromise);
1103
+ return this.visitorId ? this.visitorId : (this.visitorIdPromise || (this.visitorIdPromise = _(this.storage).then((t) => (this.visitorId = t, t))), this.visitorIdPromise);
1090
1104
  }
1091
1105
  /** Sync-доступ к visitor_id. null если ещё не зарезолвили (первые ms жизни). */
1092
1106
  getCachedVisitorId() {
@@ -1122,9 +1136,9 @@ class bt {
1122
1136
  "BillingClient in preview mode but cachedBootstrap is not seeded. Call setBootstrap(bootstrap) before open()."
1123
1137
  );
1124
1138
  }
1125
- const s = Date.now(), a = this.cachedBootstrap && this.cachedBootstrapAt > 0 && s - this.cachedBootstrapAt < _;
1139
+ const s = Date.now(), a = this.cachedBootstrap && this.cachedBootstrapAt > 0 && s - this.cachedBootstrapAt < B;
1126
1140
  return !e.force && a ? (s - this.cachedBootstrapAt > ot && this.revalidateBootstrap(e.signal).catch(() => {
1127
- }), this.cachedBootstrap) : this.inflightBootstrap ? this.inflightBootstrap : (this.inflightBootstrap = this.fetchBootstrap({
1141
+ }), { ...this.cachedBootstrap, user: this.cachedUser ?? void 0 }) : this.inflightBootstrap ? this.inflightBootstrap : (this.inflightBootstrap = this.fetchBootstrap({
1128
1142
  ifVersion: e.force ? void 0 : this.cachedBootstrap?.version,
1129
1143
  signal: e.signal
1130
1144
  }).finally(() => {
@@ -1172,7 +1186,7 @@ class bt {
1172
1186
  offers: t.offers !== void 0 ? t.offers : e.offers,
1173
1187
  version: `preview:${++this.previewVersionCounter}`
1174
1188
  };
1175
- s.layout || (s.layout = O(s.settings, s.prices)), w(s), this.cachedBootstrap = s, this.cachedBootstrapAt = Date.now();
1189
+ s.layout || (s.layout = O(s.settings, s.prices)), g(s), this.cachedBootstrap = s, this.cachedBootstrapAt = Date.now();
1176
1190
  for (const a of this.bootstrapListeners)
1177
1191
  try {
1178
1192
  a(s);
@@ -1194,7 +1208,7 @@ class bt {
1194
1208
  if ("unchanged" in a && a.unchanged)
1195
1209
  return this.cachedBootstrap ? (this.cachedBootstrapAt = Date.now(), a.user && this.applyUser(a.user), this.cachedBootstrap) : this.fetchBootstrap({ signal: t.signal });
1196
1210
  const n = a;
1197
- return n.layout || (n.layout = O(n.settings, n.prices)), w(n), this.applyBootstrap(n, { persist: !0 }), n.user && this.applyUser(n.user), n;
1211
+ return n.layout || (n.layout = O(n.settings, n.prices)), g(n), this.applyBootstrap(n, { persist: !0 }), n.user && this.applyUser(n.user), n;
1198
1212
  }
1199
1213
  // Фоновый revalidate из stale-while-revalidate ветки. Дедуплицируется через
1200
1214
  // `inflightBootstrap`, чтобы параллельные revalidate'ы не пересекались.
@@ -1227,8 +1241,8 @@ class bt {
1227
1241
  const t = await this.storage.getItem(y.bootstrap(this.paywallId));
1228
1242
  if (!t) return;
1229
1243
  const e = JSON.parse(t);
1230
- if (!e?.bootstrap || Date.now() - e.at > _ || this.cachedBootstrap) return;
1231
- w(e.bootstrap), this.cachedBootstrap = e.bootstrap, this.cachedBootstrapAt = e.at;
1244
+ if (!e?.bootstrap || Date.now() - e.at > B || this.cachedBootstrap) return;
1245
+ g(e.bootstrap), this.cachedBootstrap = e.bootstrap, this.cachedBootstrapAt = e.at;
1232
1246
  for (const s of this.bootstrapListeners)
1233
1247
  try {
1234
1248
  s(e.bootstrap);
@@ -1264,7 +1278,7 @@ class bt {
1264
1278
  this.cachedBootstrapAt = e.at;
1265
1279
  return;
1266
1280
  }
1267
- w(e.bootstrap), this.applyBootstrap(e.bootstrap, { persist: !1 });
1281
+ g(e.bootstrap), this.applyBootstrap(e.bootstrap, { persist: !1 });
1268
1282
  } catch {
1269
1283
  }
1270
1284
  }
@@ -1311,7 +1325,7 @@ class bt {
1311
1325
  * есть `navigator.language`.
1312
1326
  */
1313
1327
  getUserLanguage() {
1314
- const t = typeof navigator < "u" && navigator.language ? navigator.language : null, e = this.cachedBootstrap?.settings.locale_default ?? null, s = this.cachedBootstrap ? $(this.cachedBootstrap) : null;
1328
+ const t = typeof navigator < "u" && navigator.language ? navigator.language : null, e = this.cachedBootstrap?.settings.locale_default ?? null, s = this.cachedBootstrap ? M(this.cachedBootstrap) : null;
1315
1329
  return { tag: s ?? t ?? e, applied: s, browserLanguage: t, countryLanguage: e };
1316
1330
  }
1317
1331
  /**
@@ -1326,7 +1340,7 @@ class bt {
1326
1340
  return !t && this.cachedUser && Date.now() - this.cachedUserAt < nt ? this.cachedUser : this.inflightUser ? this.inflightUser : (this.inflightUser = (async () => {
1327
1341
  try {
1328
1342
  if (!this.identity?.email)
1329
- return this.applyUser(k), k;
1343
+ return this.applyUser(A), A;
1330
1344
  const s = await this.api.request(
1331
1345
  `/api/v1/paywall/${this.paywallId}/user-state`,
1332
1346
  { headers: { "X-User-Email": this.identity.email }, signal: e }
@@ -1391,7 +1405,7 @@ class bt {
1391
1405
  }
1392
1406
  }
1393
1407
  storageKey() {
1394
- return y.userState(this.paywallId, A(this.identity));
1408
+ return y.userState(this.paywallId, k(this.identity));
1395
1409
  }
1396
1410
  async hydrateUserFromStorage() {
1397
1411
  if (!this.cachedUser)
@@ -1546,7 +1560,7 @@ class bt {
1546
1560
  }
1547
1561
  }
1548
1562
  balancesStorageKey() {
1549
- return y.balances(this.paywallId, A(this.identity));
1563
+ return y.balances(this.paywallId, k(this.identity));
1550
1564
  }
1551
1565
  async hydrateBalancesFromStorage() {
1552
1566
  if (!this.cachedBalances)
@@ -1600,7 +1614,7 @@ class bt {
1600
1614
  const e = t.idempotencyKey ?? `auto:${t.priceId}`, s = this.inflightCheckouts.get(e);
1601
1615
  if (s) return s;
1602
1616
  const n = {
1603
- "Idempotency-Key": t.idempotencyKey ?? M()
1617
+ "Idempotency-Key": t.idempotencyKey ?? P()
1604
1618
  };
1605
1619
  this.apiKey && (n["X-Api-Key"] = this.apiKey);
1606
1620
  const r = this.cachedBootstrap?.settings, l = t.successUrl ?? r?.success_redirect_url ?? void 0, u = t.shopUrl ?? r?.checkout_shop_url ?? void 0, d = this.api.request(`/api/v1/paywall/${this.paywallId}/start-checkout`, {
@@ -1760,7 +1774,7 @@ function O(i, t) {
1760
1774
  ]
1761
1775
  };
1762
1776
  }
1763
- function $(i) {
1777
+ function M(i) {
1764
1778
  const t = i.locales;
1765
1779
  if (!t) return null;
1766
1780
  const e = [];
@@ -1775,8 +1789,8 @@ function $(i) {
1775
1789
  if (a && Object.prototype.hasOwnProperty.call(t, a)) return a;
1776
1790
  return null;
1777
1791
  }
1778
- function w(i) {
1779
- const t = $(i);
1792
+ function g(i) {
1793
+ const t = M(i);
1780
1794
  if (!t) return;
1781
1795
  const e = i.locales?.[t];
1782
1796
  e && (e.layout && (i.layout = e.layout), e.prices && (i.prices = i.prices.map((s) => {
@@ -1786,8 +1800,8 @@ function w(i) {
1786
1800
  return "label" in a && (n.label = a.label ?? null), "description" in a && (n.description = a.description ?? null), n;
1787
1801
  })));
1788
1802
  }
1789
- const yt = 1500, pt = 20, C = 200;
1790
- class vt {
1803
+ const yt = 1500, pt = 20, E = 200;
1804
+ class St {
1791
1805
  constructor(t) {
1792
1806
  this.buffer = [], this.flushTimer = null, this.destroyed = !1, this.unloadHandler = null, this.visibilityHandler = null, this.opts = t, this.isEnabled() && this.attachUnloadHandlers();
1793
1807
  }
@@ -1802,7 +1816,7 @@ class vt {
1802
1816
  this.flush();
1803
1817
  return;
1804
1818
  }
1805
- this.buffer.length > C && (this.buffer = this.buffer.slice(-C)), this.scheduleFlush();
1819
+ this.buffer.length > E && (this.buffer = this.buffer.slice(-E)), this.scheduleFlush();
1806
1820
  }
1807
1821
  scheduleFlush() {
1808
1822
  if (this.flushTimer || this.destroyed) return;
@@ -1885,11 +1899,11 @@ class vt {
1885
1899
  this.destroyed || (this.destroyed = !0, this.flushTimer && (clearTimeout(this.flushTimer), this.flushTimer = null), this.flush(), this.detachUnloadHandlers());
1886
1900
  }
1887
1901
  }
1888
- const E = 3600 * 1e3;
1889
- function v(i) {
1902
+ const C = 3600 * 1e3;
1903
+ function S(i) {
1890
1904
  return `paywall-${i}-trial-time-first-open`;
1891
1905
  }
1892
- function S(i) {
1906
+ function v(i) {
1893
1907
  return `paywall-${i}-skip-times`;
1894
1908
  }
1895
1909
  class F {
@@ -1903,10 +1917,10 @@ class F {
1903
1917
  return this.config.mode === "time" ? this.recordTime() : this.recordOpens();
1904
1918
  }
1905
1919
  async reset() {
1906
- await this.storage.removeItem(this.config.mode === "time" ? v(this.paywallId) : S(this.paywallId));
1920
+ await this.storage.removeItem(this.config.mode === "time" ? S(this.paywallId) : v(this.paywallId));
1907
1921
  }
1908
1922
  async checkTime() {
1909
- const t = this.config.payload * E, e = await this.storage.getItem(v(this.paywallId)), s = e ? Number(e) : null;
1923
+ const t = this.config.payload * C, e = await this.storage.getItem(S(this.paywallId)), s = e ? Number(e) : null;
1910
1924
  if (!s || !Number.isFinite(s))
1911
1925
  return {
1912
1926
  mode: "time",
@@ -1927,7 +1941,7 @@ class F {
1927
1941
  };
1928
1942
  }
1929
1943
  async checkOpens() {
1930
- const t = this.config.payload, e = await this.storage.getItem(S(this.paywallId)), s = e ? Number(e) : 0, a = Number.isFinite(s) ? s : 0, n = a < t, r = Math.max(0, t - a);
1944
+ const t = this.config.payload, e = await this.storage.getItem(v(this.paywallId)), s = e ? Number(e) : 0, a = Number.isFinite(s) ? s : 0, n = a < t, r = Math.max(0, t - a);
1931
1945
  return {
1932
1946
  mode: "opens",
1933
1947
  blocked: n,
@@ -1936,7 +1950,7 @@ class F {
1936
1950
  };
1937
1951
  }
1938
1952
  async recordTime() {
1939
- const t = this.config.payload * E, e = v(this.paywallId), s = await this.storage.getItem(e);
1953
+ const t = this.config.payload * C, e = S(this.paywallId), s = await this.storage.getItem(e);
1940
1954
  let a = s ? Number(s) : null;
1941
1955
  (!a || !Number.isFinite(a)) && (a = Date.now(), await this.storage.setItem(e, String(a)));
1942
1956
  const n = a + t, r = Math.max(0, n - Date.now());
@@ -1950,7 +1964,7 @@ class F {
1950
1964
  };
1951
1965
  }
1952
1966
  async recordOpens() {
1953
- const t = this.config.payload, e = S(this.paywallId), s = await this.storage.getItem(e), a = s ? Number(s) : 0, n = Number.isFinite(a) ? a : 0, r = Math.min(t, n + 1);
1967
+ const t = this.config.payload, e = v(this.paywallId), s = await this.storage.getItem(e), a = s ? Number(s) : 0, n = Number.isFinite(a) ? a : 0, r = Math.min(t, n + 1);
1954
1968
  await this.storage.setItem(e, String(r));
1955
1969
  const l = Math.max(0, t - r);
1956
1970
  return {
@@ -1961,10 +1975,10 @@ class F {
1961
1975
  };
1962
1976
  }
1963
1977
  }
1964
- let L = !1;
1965
- class gt {
1978
+ let N = !1;
1979
+ class wt {
1966
1980
  constructor(t, e, s) {
1967
- L || (L = !0, console.warn(
1981
+ N || (N = !0, console.warn(
1968
1982
  '[paywall] trial.storage="server" is not implemented yet — falling back to client storage. State lives in localStorage; users can reset trial by clearing site data.'
1969
1983
  )), this.fallback = new F(t, e, s);
1970
1984
  }
@@ -1978,11 +1992,11 @@ class gt {
1978
1992
  return this.fallback.reset();
1979
1993
  }
1980
1994
  }
1981
- function St(i, t, e) {
1982
- return e.storage === "server" ? new gt(i, t, e) : new F(i, t, e);
1995
+ function vt(i, t, e) {
1996
+ return e.storage === "server" ? new wt(i, t, e) : new F(i, t, e);
1983
1997
  }
1984
- const It = 1;
1985
- function Bt(i) {
1998
+ const bt = 1;
1999
+ function _t(i) {
1986
2000
  return i instanceof o ? {
1987
2001
  name: "PaywallError",
1988
2002
  code: i.code,
@@ -2000,7 +2014,7 @@ function Bt(i) {
2000
2014
  message: typeof i == "string" ? i : "Unknown error"
2001
2015
  };
2002
2016
  }
2003
- function _t(i) {
2017
+ function Bt(i) {
2004
2018
  if (i.name === "PaywallError") {
2005
2019
  const e = new o(i.code, i.message, { status: i.status });
2006
2020
  return i.stack && (e.stack = i.stack), e;
@@ -2008,7 +2022,7 @@ function _t(i) {
2008
2022
  const t = new Error(i.message);
2009
2023
  return t.name = i.name, i.stack && (t.stack = i.stack), t;
2010
2024
  }
2011
- function wt(i) {
2025
+ function gt(i) {
2012
2026
  let t = !1;
2013
2027
  const e = /* @__PURE__ */ new Set(), s = /* @__PURE__ */ new Set(), a = (r) => {
2014
2028
  for (const l of e) l(r);
@@ -2040,21 +2054,21 @@ function wt(i) {
2040
2054
  }
2041
2055
  };
2042
2056
  }
2043
- function kt(i) {
2057
+ function At(i) {
2044
2058
  const t = chrome.runtime.connect({ name: i });
2045
- return wt(t);
2059
+ return gt(t);
2046
2060
  }
2047
2061
  export {
2048
2062
  mt as A,
2049
- bt as B,
2050
- vt as E,
2063
+ It as B,
2064
+ St as E,
2051
2065
  o as P,
2052
- It as a,
2053
- kt as b,
2054
- St as c,
2055
- wt as p,
2056
- _t as r,
2057
- Bt as s,
2066
+ bt as a,
2067
+ At as b,
2068
+ vt as c,
2069
+ gt as p,
2070
+ Bt as r,
2071
+ _t as s,
2058
2072
  Z as w
2059
2073
  };
2060
- //# sourceMappingURL=chrome-port-DPFUj1MP.js.map
2074
+ //# sourceMappingURL=chrome-port-BAMwPMV0.js.map