@monetize.software/sdk 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.
- package/dist/chunks/{PaywallUI-C3W0eKDo.js → PaywallUI-2bwf2scV.js} +439 -395
- package/dist/chunks/PaywallUI-2bwf2scV.js.map +1 -0
- package/dist/chunks/PaywallUI-Bu51__PT.js +26 -0
- package/dist/chunks/PaywallUI-Bu51__PT.js.map +1 -0
- package/dist/core.cjs +1 -1
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.ts +71 -6
- package/dist/core.js +296 -249
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +85 -17
- package/dist/index.js +1 -1
- package/dist/ui.cjs +1 -1
- package/dist/ui.d.ts +85 -17
- package/dist/ui.js +1 -1
- package/package.json +32 -31
- package/dist/chunks/PaywallUI-BWU_1hsh.js +0 -26
- package/dist/chunks/PaywallUI-BWU_1hsh.js.map +0 -1
- package/dist/chunks/PaywallUI-C3W0eKDo.js.map +0 -1
package/dist/core.js
CHANGED
|
@@ -3,7 +3,7 @@ class r 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
|
|
6
|
+
class D extends r {
|
|
7
7
|
constructor(t) {
|
|
8
8
|
super("not_enough_queries", t.message ?? "Not enough queries", {
|
|
9
9
|
status: 402
|
|
@@ -11,12 +11,12 @@ class q extends r {
|
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
const m = "3.0.0-alpha.0";
|
|
14
|
-
class
|
|
14
|
+
class E {
|
|
15
15
|
constructor(t) {
|
|
16
16
|
this.opts = t;
|
|
17
17
|
}
|
|
18
18
|
async request(t, e = {}) {
|
|
19
|
-
const s = new URL(t, this.opts.apiOrigin).toString(),
|
|
19
|
+
const s = new URL(t, this.opts.apiOrigin).toString(), a = this.opts.fetch ?? fetch, n = new Headers(e.headers);
|
|
20
20
|
n.set("Accept", "application/json"), n.set("X-SDK-Version", m), n.set("X-Paywall-Id", this.opts.paywallId), this.opts.capabilities?.length && n.set("X-SDK-Capabilities", this.opts.capabilities.join(","));
|
|
21
21
|
const o = await this.opts.getAuthToken?.();
|
|
22
22
|
o && n.set("Authorization", `Bearer ${o}`);
|
|
@@ -24,7 +24,7 @@ class O {
|
|
|
24
24
|
e.body && !n.has("Content-Type") && !u && n.set("Content-Type", "application/json");
|
|
25
25
|
let l;
|
|
26
26
|
try {
|
|
27
|
-
l = await
|
|
27
|
+
l = await a(s, {
|
|
28
28
|
...e,
|
|
29
29
|
headers: n,
|
|
30
30
|
credentials: "omit"
|
|
@@ -40,12 +40,16 @@ class O {
|
|
|
40
40
|
return f;
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
|
-
|
|
44
|
-
class K {
|
|
43
|
+
class q {
|
|
45
44
|
constructor(t) {
|
|
46
45
|
if (!t.paywallId)
|
|
47
46
|
throw new r("invalid_config", "paywallId is required");
|
|
48
|
-
|
|
47
|
+
if (!t.apiOrigin)
|
|
48
|
+
throw new r(
|
|
49
|
+
"invalid_config",
|
|
50
|
+
"apiOrigin is required. Pass the paywall custom_domain configured in the platform."
|
|
51
|
+
);
|
|
52
|
+
this.paywallId = t.paywallId, this.apiOrigin = t.apiOrigin, this.auth = t.auth, this.userId = t.userId, this.capabilities = t.capabilities, this.customFetch = t.fetch, this.onChargeSuccess = t.onChargeSuccess, this.onQuotaExceeded = t.onQuotaExceeded, t.userId && !t.auth && typeof window < "u" && typeof window.document < "u" && console.warn(
|
|
49
53
|
"[paywall] WARNING: ApiGatewayClient.userId set without auth in browser. Client can spoof userId. Use AuthClient + Bearer for trusted user.id."
|
|
50
54
|
);
|
|
51
55
|
}
|
|
@@ -55,19 +59,19 @@ class K {
|
|
|
55
59
|
this.apiOrigin
|
|
56
60
|
);
|
|
57
61
|
s.searchParams.set("paywall_id", this.paywallId);
|
|
58
|
-
const
|
|
59
|
-
|
|
62
|
+
const a = new Headers(t.headers);
|
|
63
|
+
a.set("X-SDK-Version", m), a.set("X-Paywall-Id", this.paywallId), this.capabilities?.length && a.set("X-SDK-Capabilities", this.capabilities.join(","));
|
|
60
64
|
const n = await this.auth?.getAccessToken();
|
|
61
|
-
n ?
|
|
65
|
+
n ? a.set("Authorization", `Bearer ${n}`) : this.userId && a.set("X-User-ID", this.userId);
|
|
62
66
|
const o = typeof FormData < "u" && t.body instanceof FormData, u = typeof Blob < "u" && t.body instanceof Blob, l = typeof ReadableStream < "u" && t.body instanceof ReadableStream, d = typeof t.body == "string";
|
|
63
67
|
let h;
|
|
64
|
-
t.body === void 0 || t.body === null ? h = void 0 : o || u || l || d ? h = t.body : (h = JSON.stringify(t.body),
|
|
68
|
+
t.body === void 0 || t.body === null ? h = void 0 : o || u || l || d ? h = t.body : (h = JSON.stringify(t.body), a.has("Content-Type") || a.set("Content-Type", "application/json"));
|
|
65
69
|
const f = this.customFetch ?? fetch;
|
|
66
70
|
let c;
|
|
67
71
|
try {
|
|
68
72
|
c = await f(s.toString(), {
|
|
69
73
|
method: t.method ?? "POST",
|
|
70
|
-
headers:
|
|
74
|
+
headers: a,
|
|
71
75
|
body: h,
|
|
72
76
|
signal: t.signal,
|
|
73
77
|
credentials: "omit"
|
|
@@ -77,11 +81,11 @@ class K {
|
|
|
77
81
|
throw new r("network_error", `Network request failed: ${R}`, { cause: p });
|
|
78
82
|
}
|
|
79
83
|
if (c.status === 402) {
|
|
80
|
-
const p = await
|
|
84
|
+
const p = await K(c);
|
|
81
85
|
throw this.onQuotaExceeded?.(p), p;
|
|
82
86
|
}
|
|
83
87
|
if (!c.ok) {
|
|
84
|
-
const p = await
|
|
88
|
+
const p = await $(c.clone());
|
|
85
89
|
throw new r(
|
|
86
90
|
p ?? `http_${c.status}`,
|
|
87
91
|
c.statusText || "Gateway request failed",
|
|
@@ -92,192 +96,196 @@ class K {
|
|
|
92
96
|
return this.onChargeSuccess?.(w), c;
|
|
93
97
|
}
|
|
94
98
|
}
|
|
95
|
-
async function
|
|
99
|
+
async function K(i) {
|
|
96
100
|
let t = {};
|
|
97
101
|
try {
|
|
98
|
-
t = await
|
|
102
|
+
t = await i.json();
|
|
99
103
|
} catch {
|
|
100
104
|
}
|
|
101
105
|
const e = t.details?.balances;
|
|
102
106
|
let s = [];
|
|
103
107
|
if (Array.isArray(e)) {
|
|
104
|
-
const
|
|
105
|
-
Array.isArray(
|
|
108
|
+
const a = e[0];
|
|
109
|
+
Array.isArray(a) ? s = a : a && Array.isArray(a.balances) && (s = a.balances);
|
|
106
110
|
}
|
|
107
|
-
return new
|
|
111
|
+
return new D({
|
|
108
112
|
balances: s,
|
|
109
113
|
queryType: t.details?.queryType ?? "",
|
|
110
114
|
currentBalance: t.details?.currentBalance ?? null
|
|
111
115
|
});
|
|
112
116
|
}
|
|
113
|
-
async function
|
|
114
|
-
if (!(
|
|
117
|
+
async function $(i) {
|
|
118
|
+
if (!(i.headers.get("content-type") ?? "").includes("application/json")) return null;
|
|
115
119
|
try {
|
|
116
|
-
const e = await
|
|
120
|
+
const e = await i.json();
|
|
117
121
|
return e.code || e.error || null;
|
|
118
122
|
} catch {
|
|
119
123
|
return null;
|
|
120
124
|
}
|
|
121
125
|
}
|
|
122
|
-
function
|
|
126
|
+
function F() {
|
|
123
127
|
return typeof chrome < "u" && !!chrome?.storage?.local && !!chrome?.runtime?.id;
|
|
124
128
|
}
|
|
125
129
|
const M = {
|
|
126
|
-
getItem(
|
|
130
|
+
getItem(i) {
|
|
127
131
|
return new Promise((t) => {
|
|
128
|
-
chrome.storage.local.get([
|
|
129
|
-
const s = e[
|
|
132
|
+
chrome.storage.local.get([i], (e) => {
|
|
133
|
+
const s = e[i];
|
|
130
134
|
t(typeof s == "string" ? s : null);
|
|
131
135
|
});
|
|
132
136
|
});
|
|
133
137
|
},
|
|
134
|
-
setItem(
|
|
138
|
+
setItem(i, t) {
|
|
135
139
|
return new Promise((e) => {
|
|
136
|
-
chrome.storage.local.set({ [
|
|
140
|
+
chrome.storage.local.set({ [i]: t }, () => e());
|
|
137
141
|
});
|
|
138
142
|
},
|
|
139
|
-
removeItem(
|
|
143
|
+
removeItem(i) {
|
|
140
144
|
return new Promise((t) => {
|
|
141
|
-
chrome.storage.local.remove([
|
|
145
|
+
chrome.storage.local.remove([i], () => t());
|
|
142
146
|
});
|
|
143
147
|
},
|
|
144
|
-
watch(
|
|
148
|
+
watch(i, t) {
|
|
145
149
|
const e = chrome?.storage?.onChanged;
|
|
146
150
|
if (!e) return () => {
|
|
147
151
|
};
|
|
148
|
-
const s = (
|
|
152
|
+
const s = (a, n) => {
|
|
149
153
|
if (n !== "local") return;
|
|
150
|
-
const o = i
|
|
154
|
+
const o = a[i];
|
|
151
155
|
o && t(typeof o.newValue == "string" ? o.newValue : null);
|
|
152
156
|
};
|
|
153
157
|
return e.addListener(s), () => e.removeListener(s);
|
|
154
158
|
}
|
|
155
159
|
}, x = {
|
|
156
|
-
async getItem(
|
|
160
|
+
async getItem(i) {
|
|
157
161
|
try {
|
|
158
|
-
return window.localStorage.getItem(
|
|
162
|
+
return window.localStorage.getItem(i);
|
|
159
163
|
} catch {
|
|
160
164
|
return null;
|
|
161
165
|
}
|
|
162
166
|
},
|
|
163
|
-
async setItem(
|
|
167
|
+
async setItem(i, t) {
|
|
164
168
|
try {
|
|
165
|
-
window.localStorage.setItem(
|
|
169
|
+
window.localStorage.setItem(i, t);
|
|
166
170
|
} catch {
|
|
167
171
|
}
|
|
168
172
|
},
|
|
169
|
-
async removeItem(
|
|
173
|
+
async removeItem(i) {
|
|
170
174
|
try {
|
|
171
|
-
window.localStorage.removeItem(
|
|
175
|
+
window.localStorage.removeItem(i);
|
|
172
176
|
} catch {
|
|
173
177
|
}
|
|
174
178
|
},
|
|
175
|
-
watch(
|
|
179
|
+
watch(i, t) {
|
|
176
180
|
if (typeof window > "u") return () => {
|
|
177
181
|
};
|
|
178
182
|
const e = (s) => {
|
|
179
|
-
s.storageArea === window.localStorage && s.key ===
|
|
183
|
+
s.storageArea === window.localStorage && s.key === i && t(s.newValue);
|
|
180
184
|
};
|
|
181
185
|
return window.addEventListener("storage", e), () => window.removeEventListener("storage", e);
|
|
182
186
|
}
|
|
183
|
-
},
|
|
184
|
-
async getItem(
|
|
185
|
-
return
|
|
187
|
+
}, v = /* @__PURE__ */ new Map(), J = {
|
|
188
|
+
async getItem(i) {
|
|
189
|
+
return v.get(i) ?? null;
|
|
186
190
|
},
|
|
187
|
-
async setItem(
|
|
188
|
-
|
|
191
|
+
async setItem(i, t) {
|
|
192
|
+
v.set(i, t);
|
|
189
193
|
},
|
|
190
|
-
async removeItem(
|
|
191
|
-
|
|
194
|
+
async removeItem(i) {
|
|
195
|
+
v.delete(i);
|
|
192
196
|
}
|
|
193
197
|
};
|
|
194
|
-
function C(
|
|
195
|
-
return
|
|
198
|
+
function C(i) {
|
|
199
|
+
return i || (F() ? M : typeof window < "u" && "localStorage" in window ? x : J);
|
|
196
200
|
}
|
|
197
201
|
const y = {
|
|
198
202
|
visitorId: "pw-visitor-id",
|
|
199
|
-
lastLoginMethod: (
|
|
200
|
-
lastLoginEmail: (
|
|
203
|
+
lastLoginMethod: (i) => `pw-${i}-last-login-method`,
|
|
204
|
+
lastLoginEmail: (i) => `pw-${i}-last-login-email`,
|
|
201
205
|
// last-known PaywallUser. Используется как offline-fallback на старте, пока
|
|
202
206
|
// первый getUser() не вернётся. Ключ зависит от paywallId+identity hash —
|
|
203
207
|
// переключение identity не должно отдавать чужой user.
|
|
204
|
-
userState: (
|
|
208
|
+
userState: (i, t) => `pw-${i}-${t}-user-v1`,
|
|
205
209
|
// Persisted auth bundle (access_token, refresh_token, expires_at, user) для
|
|
206
210
|
// одного пейвола. Ключ привязан к paywallId — мульти-пейвольное приложение
|
|
207
211
|
// не пересекает сессии. Bump '-v1' на breaking shape change.
|
|
208
|
-
authSession: (
|
|
212
|
+
authSession: (i) => `pw-${i}-auth-v1`,
|
|
209
213
|
// Refresh-token последнего анонимного юзера. Хранится отдельно от authSession,
|
|
210
214
|
// потому что должен пережить signOut: после signOut() юзер может опять
|
|
211
215
|
// зайти как тот же аноним — без капчи, через этот токен. signIn другим
|
|
212
216
|
// методом (email/oauth) тоже его не трогает. Чистится только явным
|
|
213
217
|
// signOut({forgetAnonymous: true}) или 401 от refresh-эндпоинта (значит
|
|
214
218
|
// токен отозван, дальше держать бессмысленно).
|
|
215
|
-
anonRefreshToken: (
|
|
219
|
+
anonRefreshToken: (i) => `pw-${i}-anon-rt-v1`,
|
|
216
220
|
// Persisted bootstrap (settings/prices/offers/layout/locales/version) для
|
|
217
221
|
// stale-while-revalidate. Не зависит от identity — layout одинаков для всех
|
|
218
222
|
// юзеров одного пейвола; user-state живёт отдельно под `userState(...)`.
|
|
219
223
|
// Bump '-v1' на breaking shape change.
|
|
220
|
-
bootstrap: (
|
|
224
|
+
bootstrap: (i) => `pw-${i}-bootstrap-v1`,
|
|
221
225
|
// Persisted balances (AI-провайдеры × tokenization_queries). Identity-bound,
|
|
222
226
|
// т.к. balance считается per-Bearer-юзеру; при re-login ключ меняется и
|
|
223
227
|
// чужие balances не видны. Меняются после оплаты (бэк) и API-вызовов
|
|
224
228
|
// (оптимистично через `decrementBalanceLocal`).
|
|
225
|
-
balances: (
|
|
229
|
+
balances: (i, t) => `pw-${i}-${t}-balances-v1`
|
|
226
230
|
};
|
|
227
|
-
function
|
|
228
|
-
const
|
|
229
|
-
if (
|
|
231
|
+
function N() {
|
|
232
|
+
const i = typeof globalThis < "u" ? globalThis.crypto : void 0;
|
|
233
|
+
if (i && typeof i.randomUUID == "function") return i.randomUUID();
|
|
230
234
|
const t = new Uint8Array(16);
|
|
231
|
-
if (
|
|
232
|
-
|
|
235
|
+
if (i && typeof i.getRandomValues == "function")
|
|
236
|
+
i.getRandomValues(t);
|
|
233
237
|
else
|
|
234
238
|
for (let s = 0; s < 16; s++) t[s] = Math.floor(Math.random() * 256);
|
|
235
239
|
t[6] = t[6] & 15 | 64, t[8] = t[8] & 63 | 128;
|
|
236
240
|
const e = Array.from(t, (s) => s.toString(16).padStart(2, "0")).join("");
|
|
237
241
|
return `${e.slice(0, 8)}-${e.slice(8, 12)}-${e.slice(12, 16)}-${e.slice(16, 20)}-${e.slice(20)}`;
|
|
238
242
|
}
|
|
239
|
-
async function
|
|
243
|
+
async function I(i) {
|
|
240
244
|
try {
|
|
241
|
-
const e = await
|
|
245
|
+
const e = await i.getItem(y.visitorId);
|
|
242
246
|
if (e && typeof e == "string" && e.length >= 16) return e;
|
|
243
247
|
} catch {
|
|
244
248
|
}
|
|
245
|
-
const t =
|
|
249
|
+
const t = N();
|
|
246
250
|
try {
|
|
247
|
-
await
|
|
251
|
+
await i.setItem(y.visitorId, t);
|
|
248
252
|
} catch {
|
|
249
253
|
}
|
|
250
254
|
return t;
|
|
251
255
|
}
|
|
252
|
-
const H = 5e3, V = 30 * 6e4,
|
|
256
|
+
const H = 5e3, V = 30 * 6e4, b = 60 * 6e4, j = 5 * 6e4, _ = {
|
|
253
257
|
has_active_subscription: !1,
|
|
254
258
|
purchases: [],
|
|
255
259
|
trial: null
|
|
256
260
|
};
|
|
257
|
-
function
|
|
258
|
-
return
|
|
261
|
+
function B(i) {
|
|
262
|
+
return i && (i.email || i.userId || i.anonymousId) || "guest";
|
|
259
263
|
}
|
|
260
|
-
function
|
|
261
|
-
return
|
|
264
|
+
function G(i, t) {
|
|
265
|
+
return i === t ? !0 : !i || !t ? !1 : JSON.stringify(i) === JSON.stringify(t);
|
|
262
266
|
}
|
|
263
|
-
const
|
|
264
|
-
function Q(
|
|
265
|
-
if (
|
|
266
|
-
if (!
|
|
267
|
-
for (let e = 0; e <
|
|
268
|
-
if (
|
|
267
|
+
const X = 5e3, A = 5 * 6e4, z = 3e4;
|
|
268
|
+
function Q(i, t) {
|
|
269
|
+
if (i === t) return !0;
|
|
270
|
+
if (!i || !t || i.length !== t.length) return !1;
|
|
271
|
+
for (let e = 0; e < i.length; e++)
|
|
272
|
+
if (i[e].type !== t[e].type || i[e].count !== t[e].count) return !1;
|
|
269
273
|
return !0;
|
|
270
274
|
}
|
|
271
|
-
|
|
272
|
-
class ut {
|
|
275
|
+
class lt {
|
|
273
276
|
constructor(t) {
|
|
274
277
|
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)
|
|
275
278
|
throw new r("invalid_config", "paywallId is required");
|
|
276
|
-
|
|
279
|
+
if (!t.apiOrigin)
|
|
280
|
+
throw new r(
|
|
281
|
+
"invalid_config",
|
|
282
|
+
'apiOrigin is required. Pass the paywall custom_domain configured in the platform (e.g. "https://pay.your-domain.com"). The legacy "appbox.space" fallback is not used in SDK 3.0.'
|
|
283
|
+
);
|
|
284
|
+
this.paywallId = t.paywallId, this.apiOrigin = t.apiOrigin, this.capabilities = t.capabilities, this.auth = t.auth, this.previewMode = t.preview === !0;
|
|
277
285
|
const e = t.auth?.getCachedUser();
|
|
278
286
|
this.identity = t.identity ?? (e ? T(e) : void 0), this.apiKey = t.apiKey, this.fetchImpl = t.fetch, t.apiKey && typeof window < "u" && typeof window.document < "u" && console.error(
|
|
279
287
|
"[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."
|
|
280
|
-
), this.storage = C(t.storage), this.api = new
|
|
288
|
+
), this.storage = C(t.storage), this.api = new E({
|
|
281
289
|
apiOrigin: this.apiOrigin,
|
|
282
290
|
paywallId: t.paywallId,
|
|
283
291
|
capabilities: t.capabilities,
|
|
@@ -286,10 +294,10 @@ class ut {
|
|
|
286
294
|
// делает lazy refresh, дедупит, на 401 возвращает null — тогда
|
|
287
295
|
// Authorization-хедер просто не выставится.
|
|
288
296
|
getAuthToken: t.auth ? () => t.auth.getAccessToken() : void 0
|
|
289
|
-
}), t.auth && (this.authUnsubscribe = t.auth.onAuthChange((s) => {
|
|
290
|
-
const
|
|
291
|
-
|
|
292
|
-
})), this.hydrateUserFromStorage(), this.hydrateBootstrapFromStorage(), this.subscribeBootstrapStorage(), this.hydrateBalancesFromStorage(), this.subscribeBalancesStorage(), this.visitorIdPromise =
|
|
297
|
+
}), t.auth && (this.authUnsubscribe = t.auth.onAuthChange((s, a) => {
|
|
298
|
+
const n = a ? T(a.user) : void 0;
|
|
299
|
+
W(this.identity, n) || this.setIdentity(n);
|
|
300
|
+
})), this.hydrateUserFromStorage(), this.hydrateBootstrapFromStorage(), this.subscribeBootstrapStorage(), this.hydrateBalancesFromStorage(), this.subscribeBalancesStorage(), this.visitorIdPromise = I(this.storage).then((s) => (this.visitorId = s, s));
|
|
293
301
|
}
|
|
294
302
|
/**
|
|
295
303
|
* Stable visitor_id (UUID v4). Первый вызов awaitит первичный резолв из
|
|
@@ -297,7 +305,7 @@ class ut {
|
|
|
297
305
|
* EventTracker'ом для атрибуции аналитики.
|
|
298
306
|
*/
|
|
299
307
|
async getVisitorId() {
|
|
300
|
-
return this.visitorId ? this.visitorId : (this.visitorIdPromise || (this.visitorIdPromise =
|
|
308
|
+
return this.visitorId ? this.visitorId : (this.visitorIdPromise || (this.visitorIdPromise = I(this.storage).then((t) => (this.visitorId = t, t))), this.visitorIdPromise);
|
|
301
309
|
}
|
|
302
310
|
/** Sync-доступ к visitor_id. null если ещё не зарезолвили (первые ms жизни). */
|
|
303
311
|
getCachedVisitorId() {
|
|
@@ -333,9 +341,9 @@ class ut {
|
|
|
333
341
|
"BillingClient in preview mode but cachedBootstrap is not seeded. Call setBootstrap(bootstrap) before open()."
|
|
334
342
|
);
|
|
335
343
|
}
|
|
336
|
-
const s = Date.now(),
|
|
337
|
-
return !e.force &&
|
|
338
|
-
}), this.cachedBootstrap) : this.inflightBootstrap ? this.inflightBootstrap : (this.inflightBootstrap = this.fetchBootstrap({
|
|
344
|
+
const s = Date.now(), a = this.cachedBootstrap && this.cachedBootstrapAt > 0 && s - this.cachedBootstrapAt < b;
|
|
345
|
+
return !e.force && a ? (s - this.cachedBootstrapAt > j && this.revalidateBootstrap(e.signal).catch(() => {
|
|
346
|
+
}), { ...this.cachedBootstrap, user: this.cachedUser ?? void 0 }) : this.inflightBootstrap ? this.inflightBootstrap : (this.inflightBootstrap = this.fetchBootstrap({
|
|
339
347
|
ifVersion: e.force ? void 0 : this.cachedBootstrap?.version,
|
|
340
348
|
signal: e.signal
|
|
341
349
|
}).finally(() => {
|
|
@@ -384,9 +392,9 @@ class ut {
|
|
|
384
392
|
version: `preview:${++this.previewVersionCounter}`
|
|
385
393
|
};
|
|
386
394
|
s.layout || (s.layout = U(s.settings, s.prices)), g(s), this.cachedBootstrap = s, this.cachedBootstrapAt = Date.now();
|
|
387
|
-
for (const
|
|
395
|
+
for (const a of this.bootstrapListeners)
|
|
388
396
|
try {
|
|
389
|
-
|
|
397
|
+
a(s);
|
|
390
398
|
} catch (n) {
|
|
391
399
|
console.warn("[paywall] onBootstrapChange listener threw", n);
|
|
392
400
|
}
|
|
@@ -398,14 +406,14 @@ class ut {
|
|
|
398
406
|
async fetchBootstrap(t) {
|
|
399
407
|
const e = {};
|
|
400
408
|
this.identity?.email && (e["X-User-Email"] = this.identity.email);
|
|
401
|
-
const s = t.ifVersion ? `/api/v1/paywall/${this.paywallId}/bootstrap?if_version=${encodeURIComponent(t.ifVersion)}` : `/api/v1/paywall/${this.paywallId}/bootstrap`,
|
|
409
|
+
const s = t.ifVersion ? `/api/v1/paywall/${this.paywallId}/bootstrap?if_version=${encodeURIComponent(t.ifVersion)}` : `/api/v1/paywall/${this.paywallId}/bootstrap`, a = await this.api.request(s, {
|
|
402
410
|
...Object.keys(e).length ? { headers: e } : {},
|
|
403
411
|
signal: t.signal
|
|
404
412
|
});
|
|
405
|
-
if ("unchanged" in
|
|
406
|
-
return this.cachedBootstrap ? (this.cachedBootstrapAt = Date.now(),
|
|
407
|
-
const n =
|
|
408
|
-
return n.layout || (n.layout = U(n.settings, n.prices)), g(n), this.applyBootstrap(n, { persist: !0 }), n.user && this.applyUser(n.user), n;
|
|
413
|
+
if ("unchanged" in a && a.unchanged)
|
|
414
|
+
return this.cachedBootstrap ? (this.cachedBootstrapAt = Date.now(), a.user && this.applyUser(a.user), this.cachedBootstrap) : this.fetchBootstrap({ signal: t.signal });
|
|
415
|
+
const n = a;
|
|
416
|
+
return Y(n.settings.custom_domain, this.apiOrigin), n.layout || (n.layout = U(n.settings, n.prices)), g(n), this.applyBootstrap(n, { persist: !0 }), n.user && this.applyUser(n.user), n;
|
|
409
417
|
}
|
|
410
418
|
// Фоновый revalidate из stale-while-revalidate ветки. Дедуплицируется через
|
|
411
419
|
// `inflightBootstrap`, чтобы параллельные revalidate'ы не пересекались.
|
|
@@ -425,9 +433,9 @@ class ut {
|
|
|
425
433
|
applyBootstrap(t, { persist: e }) {
|
|
426
434
|
const s = !this.cachedBootstrap || this.cachedBootstrap.version !== t.version;
|
|
427
435
|
if (this.cachedBootstrap = t, this.cachedBootstrapAt = Date.now(), e && this.persistBootstrap(t), s)
|
|
428
|
-
for (const
|
|
436
|
+
for (const a of this.bootstrapListeners)
|
|
429
437
|
try {
|
|
430
|
-
|
|
438
|
+
a(t);
|
|
431
439
|
} catch (n) {
|
|
432
440
|
console.warn("[paywall] onBootstrapChange listener threw", n);
|
|
433
441
|
}
|
|
@@ -438,13 +446,13 @@ class ut {
|
|
|
438
446
|
const t = await this.storage.getItem(y.bootstrap(this.paywallId));
|
|
439
447
|
if (!t) return;
|
|
440
448
|
const e = JSON.parse(t);
|
|
441
|
-
if (!e?.bootstrap || Date.now() - e.at >
|
|
449
|
+
if (!e?.bootstrap || Date.now() - e.at > b || this.cachedBootstrap) return;
|
|
442
450
|
g(e.bootstrap), this.cachedBootstrap = e.bootstrap, this.cachedBootstrapAt = e.at;
|
|
443
451
|
for (const s of this.bootstrapListeners)
|
|
444
452
|
try {
|
|
445
453
|
s(e.bootstrap);
|
|
446
|
-
} catch (
|
|
447
|
-
console.warn("[paywall] onBootstrapChange listener threw",
|
|
454
|
+
} catch (a) {
|
|
455
|
+
console.warn("[paywall] onBootstrapChange listener threw", a);
|
|
448
456
|
}
|
|
449
457
|
} catch {
|
|
450
458
|
}
|
|
@@ -537,7 +545,7 @@ class ut {
|
|
|
537
545
|
return !t && this.cachedUser && Date.now() - this.cachedUserAt < H ? this.cachedUser : this.inflightUser ? this.inflightUser : (this.inflightUser = (async () => {
|
|
538
546
|
try {
|
|
539
547
|
if (!this.identity?.email)
|
|
540
|
-
return this.applyUser(
|
|
548
|
+
return this.applyUser(_), _;
|
|
541
549
|
const s = await this.api.request(
|
|
542
550
|
`/api/v1/paywall/${this.paywallId}/user-state`,
|
|
543
551
|
{ headers: { "X-User-Email": this.identity.email }, signal: e }
|
|
@@ -569,16 +577,16 @@ class ut {
|
|
|
569
577
|
this.userListeners.add(t);
|
|
570
578
|
const s = e.immediate ?? "microtask";
|
|
571
579
|
if (this.cachedUser && s !== "none") {
|
|
572
|
-
const
|
|
580
|
+
const a = this.cachedUser;
|
|
573
581
|
if (s === "sync")
|
|
574
582
|
try {
|
|
575
|
-
t(
|
|
583
|
+
t(a);
|
|
576
584
|
} catch (n) {
|
|
577
585
|
console.warn("[paywall] onUserChange initial sync threw", n);
|
|
578
586
|
}
|
|
579
587
|
else
|
|
580
588
|
queueMicrotask(() => {
|
|
581
|
-
this.userListeners.has(t) && t(
|
|
589
|
+
this.userListeners.has(t) && t(a);
|
|
582
590
|
});
|
|
583
591
|
}
|
|
584
592
|
return () => {
|
|
@@ -590,19 +598,19 @@ class ut {
|
|
|
590
598
|
return this.cachedUser;
|
|
591
599
|
}
|
|
592
600
|
applyUser(t) {
|
|
593
|
-
const e = !
|
|
601
|
+
const e = !G(this.cachedUser, t);
|
|
594
602
|
if (this.cachedUser = t, this.cachedUserAt = Date.now(), e) {
|
|
595
603
|
this.persistUser(t);
|
|
596
604
|
for (const s of this.userListeners)
|
|
597
605
|
try {
|
|
598
606
|
s(t);
|
|
599
|
-
} catch (
|
|
600
|
-
console.warn("[paywall] onUserChange listener threw",
|
|
607
|
+
} catch (a) {
|
|
608
|
+
console.warn("[paywall] onUserChange listener threw", a);
|
|
601
609
|
}
|
|
602
610
|
}
|
|
603
611
|
}
|
|
604
612
|
storageKey() {
|
|
605
|
-
return y.userState(this.paywallId,
|
|
613
|
+
return y.userState(this.paywallId, B(this.identity));
|
|
606
614
|
}
|
|
607
615
|
async hydrateUserFromStorage() {
|
|
608
616
|
if (!this.cachedUser)
|
|
@@ -638,8 +646,8 @@ class ut {
|
|
|
638
646
|
* по `currentBalance` в QuotaExceededError или `balances.length`.
|
|
639
647
|
*/
|
|
640
648
|
async getBalances({ force: t = !1, signal: e } = {}) {
|
|
641
|
-
const s = Date.now(),
|
|
642
|
-
return !t && this.cachedBalances && (
|
|
649
|
+
const s = Date.now(), a = this.cachedBalances ? s - this.cachedBalancesAt : 1 / 0;
|
|
650
|
+
return !t && this.cachedBalances && (a < X || a < z) ? this.cachedBalances : !t && this.cachedBalances && a < A ? (this.fetchBalances({ signal: e }).catch(() => {
|
|
643
651
|
}), this.cachedBalances) : this.inflightBalances ? this.inflightBalances : this.fetchBalances({ signal: e });
|
|
644
652
|
}
|
|
645
653
|
// Network primitive — единая точка для force/stale-revalidate/cold-start.
|
|
@@ -670,16 +678,16 @@ class ut {
|
|
|
670
678
|
this.balanceListeners.add(t);
|
|
671
679
|
const s = e.immediate ?? "microtask";
|
|
672
680
|
if (this.cachedBalances && s !== "none") {
|
|
673
|
-
const
|
|
681
|
+
const a = this.cachedBalances;
|
|
674
682
|
if (s === "sync")
|
|
675
683
|
try {
|
|
676
|
-
t(
|
|
684
|
+
t(a);
|
|
677
685
|
} catch (n) {
|
|
678
686
|
console.warn("[paywall] onBalanceChange initial sync threw", n);
|
|
679
687
|
}
|
|
680
688
|
else
|
|
681
689
|
queueMicrotask(() => {
|
|
682
|
-
this.balanceListeners.has(t) && t(
|
|
690
|
+
this.balanceListeners.has(t) && t(a);
|
|
683
691
|
});
|
|
684
692
|
}
|
|
685
693
|
return () => {
|
|
@@ -708,10 +716,10 @@ class ut {
|
|
|
708
716
|
if (!this.cachedBalances) return;
|
|
709
717
|
const e = this.cachedBalances.findIndex((n) => n.type === t);
|
|
710
718
|
if (e < 0 || this.cachedBalances[e].count <= 0) return;
|
|
711
|
-
const
|
|
719
|
+
const a = this.cachedBalances.map(
|
|
712
720
|
(n, o) => o === e ? { ...n, count: n.count - 1 } : n
|
|
713
721
|
);
|
|
714
|
-
this.applyBalances(
|
|
722
|
+
this.applyBalances(a);
|
|
715
723
|
}
|
|
716
724
|
/** Принудительный re-fetch — типичный вызов после QuotaExceededError, чтобы
|
|
717
725
|
* UI получил актуальный balance=0 и нарисовал upgrade-prompt. */
|
|
@@ -730,7 +738,7 @@ class ut {
|
|
|
730
738
|
*/
|
|
731
739
|
createApiGatewayClient(t = {}) {
|
|
732
740
|
const e = t.onChargeSuccess, s = t.onQuotaExceeded;
|
|
733
|
-
return new
|
|
741
|
+
return new q({
|
|
734
742
|
paywallId: this.paywallId,
|
|
735
743
|
apiOrigin: this.apiOrigin,
|
|
736
744
|
auth: this.auth,
|
|
@@ -738,26 +746,26 @@ class ut {
|
|
|
738
746
|
capabilities: this.capabilities,
|
|
739
747
|
fetch: this.fetchImpl,
|
|
740
748
|
...t,
|
|
741
|
-
onChargeSuccess: (
|
|
742
|
-
this.decrementBalanceLocal(
|
|
749
|
+
onChargeSuccess: (a) => {
|
|
750
|
+
this.decrementBalanceLocal(a), e?.(a);
|
|
743
751
|
},
|
|
744
|
-
onQuotaExceeded: (
|
|
745
|
-
this.refreshBalances(), s?.(
|
|
752
|
+
onQuotaExceeded: (a) => {
|
|
753
|
+
this.refreshBalances(), s?.(a);
|
|
746
754
|
}
|
|
747
755
|
});
|
|
748
756
|
}
|
|
749
757
|
applyBalances(t, { persist: e = !0 } = {}) {
|
|
750
758
|
const s = !Q(this.cachedBalances, t);
|
|
751
759
|
if (this.cachedBalances = t, this.cachedBalancesAt = Date.now(), e && this.persistBalances(t), s)
|
|
752
|
-
for (const
|
|
760
|
+
for (const a of this.balanceListeners)
|
|
753
761
|
try {
|
|
754
|
-
|
|
762
|
+
a(t);
|
|
755
763
|
} catch (n) {
|
|
756
764
|
console.warn("[paywall] onBalanceChange listener threw", n);
|
|
757
765
|
}
|
|
758
766
|
}
|
|
759
767
|
balancesStorageKey() {
|
|
760
|
-
return y.balances(this.paywallId,
|
|
768
|
+
return y.balances(this.paywallId, B(this.identity));
|
|
761
769
|
}
|
|
762
770
|
async hydrateBalancesFromStorage() {
|
|
763
771
|
if (!this.cachedBalances)
|
|
@@ -770,8 +778,8 @@ class ut {
|
|
|
770
778
|
for (const s of this.balanceListeners)
|
|
771
779
|
try {
|
|
772
780
|
s(e.balances);
|
|
773
|
-
} catch (
|
|
774
|
-
console.warn("[paywall] onBalanceChange listener threw",
|
|
781
|
+
} catch (a) {
|
|
782
|
+
console.warn("[paywall] onBalanceChange listener threw", a);
|
|
775
783
|
}
|
|
776
784
|
} catch {
|
|
777
785
|
}
|
|
@@ -811,7 +819,7 @@ class ut {
|
|
|
811
819
|
const e = t.idempotencyKey ?? `auto:${t.priceId}`, s = this.inflightCheckouts.get(e);
|
|
812
820
|
if (s) return s;
|
|
813
821
|
const n = {
|
|
814
|
-
"Idempotency-Key": t.idempotencyKey ??
|
|
822
|
+
"Idempotency-Key": t.idempotencyKey ?? N()
|
|
815
823
|
};
|
|
816
824
|
this.apiKey && (n["X-Api-Key"] = this.apiKey);
|
|
817
825
|
const o = this.cachedBootstrap?.settings, u = t.successUrl ?? o?.success_redirect_url ?? void 0, l = t.shopUrl ?? o?.checkout_shop_url ?? void 0, d = this.api.request(`/api/v1/paywall/${this.paywallId}/start-checkout`, {
|
|
@@ -955,80 +963,105 @@ class ut {
|
|
|
955
963
|
});
|
|
956
964
|
}
|
|
957
965
|
}
|
|
958
|
-
function T(
|
|
959
|
-
return { email:
|
|
966
|
+
function T(i) {
|
|
967
|
+
return { email: i.email, userId: i.id };
|
|
968
|
+
}
|
|
969
|
+
function W(i, t) {
|
|
970
|
+
return i === t ? !0 : !i || !t ? !1 : i.email === t.email && i.userId === t.userId && i.anonymousId === t.anonymousId;
|
|
960
971
|
}
|
|
961
|
-
function
|
|
962
|
-
|
|
972
|
+
function O(i) {
|
|
973
|
+
if (!i) return null;
|
|
974
|
+
const t = i.trim();
|
|
975
|
+
if (!t) return null;
|
|
976
|
+
try {
|
|
977
|
+
return new URL(t.includes("://") ? t : `https://${t}`).origin;
|
|
978
|
+
} catch {
|
|
979
|
+
return null;
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
function Y(i, t) {
|
|
983
|
+
const e = O(i);
|
|
984
|
+
if (!(!e || O(t) === e))
|
|
985
|
+
throw new r(
|
|
986
|
+
"invalid_config",
|
|
987
|
+
`apiOrigin mismatch: SDK initialized with "${t}" but paywall is configured with custom_domain "${i}". Use the custom_domain from the platform paywall settings.`
|
|
988
|
+
);
|
|
963
989
|
}
|
|
964
|
-
function U(
|
|
990
|
+
function U(i, t) {
|
|
965
991
|
return {
|
|
966
992
|
type: "modal",
|
|
967
993
|
blocks: [
|
|
968
|
-
{ type: "heading", text:
|
|
994
|
+
{ type: "heading", text: i.name || "Upgrade", level: 1 },
|
|
969
995
|
{ type: "price_grid", priceIds: t.map((e) => e.id) },
|
|
970
|
-
{ type: "cta_button", label: "Continue", action: "checkout" }
|
|
996
|
+
{ type: "cta_button", label: "Continue", action: "checkout" },
|
|
997
|
+
{ type: "guarantee_badge" },
|
|
998
|
+
{ type: "current_session" }
|
|
971
999
|
]
|
|
972
1000
|
};
|
|
973
1001
|
}
|
|
974
|
-
function L(
|
|
975
|
-
const t =
|
|
1002
|
+
function L(i) {
|
|
1003
|
+
const t = i.locales;
|
|
976
1004
|
if (!t) return null;
|
|
977
1005
|
const e = [];
|
|
978
1006
|
if (typeof navigator < "u") {
|
|
979
1007
|
navigator.language && e.push(navigator.language);
|
|
980
|
-
const
|
|
981
|
-
|
|
1008
|
+
const a = navigator.language?.split("-")[0];
|
|
1009
|
+
a && a !== navigator.language && e.push(a);
|
|
982
1010
|
}
|
|
983
|
-
const s =
|
|
1011
|
+
const s = i.settings.locale_default;
|
|
984
1012
|
s && e.push(s);
|
|
985
|
-
for (const
|
|
986
|
-
if (
|
|
1013
|
+
for (const a of e)
|
|
1014
|
+
if (a && Object.prototype.hasOwnProperty.call(t, a)) return a;
|
|
987
1015
|
return null;
|
|
988
1016
|
}
|
|
989
|
-
function g(
|
|
990
|
-
const t = L(
|
|
1017
|
+
function g(i) {
|
|
1018
|
+
const t = L(i);
|
|
991
1019
|
if (!t) return;
|
|
992
|
-
const e =
|
|
993
|
-
e && (e.layout && (
|
|
994
|
-
const
|
|
995
|
-
if (!
|
|
1020
|
+
const e = i.locales?.[t];
|
|
1021
|
+
e && (e.layout && (i.layout = e.layout), e.prices && (i.prices = i.prices.map((s) => {
|
|
1022
|
+
const a = e.prices?.[s.id];
|
|
1023
|
+
if (!a) return s;
|
|
996
1024
|
const n = { ...s };
|
|
997
|
-
return "label" in
|
|
1025
|
+
return "label" in a && (n.label = a.label ?? null), "description" in a && (n.description = a.description ?? null), n;
|
|
998
1026
|
})));
|
|
999
1027
|
}
|
|
1000
|
-
function P(
|
|
1001
|
-
const t = new Uint8Array(
|
|
1028
|
+
function P(i) {
|
|
1029
|
+
const t = new Uint8Array(i), e = typeof globalThis < "u" ? globalThis.crypto : void 0;
|
|
1002
1030
|
if (e && typeof e.getRandomValues == "function")
|
|
1003
1031
|
e.getRandomValues(t);
|
|
1004
1032
|
else
|
|
1005
|
-
for (let s = 0; s <
|
|
1033
|
+
for (let s = 0; s < i; s++) t[s] = Math.floor(Math.random() * 256);
|
|
1006
1034
|
return t;
|
|
1007
1035
|
}
|
|
1008
|
-
function
|
|
1036
|
+
function S(i) {
|
|
1009
1037
|
let t = "";
|
|
1010
|
-
for (let e = 0; e <
|
|
1038
|
+
for (let e = 0; e < i.length; e++) t += String.fromCharCode(i[e]);
|
|
1011
1039
|
return btoa(t).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
1012
1040
|
}
|
|
1013
1041
|
function Z() {
|
|
1014
|
-
return
|
|
1042
|
+
return S(P(64));
|
|
1015
1043
|
}
|
|
1016
|
-
async function tt(
|
|
1017
|
-
const t = new TextEncoder().encode(
|
|
1044
|
+
async function tt(i) {
|
|
1045
|
+
const t = new TextEncoder().encode(i), e = globalThis.crypto;
|
|
1018
1046
|
if (!e?.subtle?.digest)
|
|
1019
1047
|
throw new Error("crypto.subtle is required for PKCE");
|
|
1020
1048
|
const s = await e.subtle.digest("SHA-256", t);
|
|
1021
|
-
return
|
|
1049
|
+
return S(new Uint8Array(s));
|
|
1022
1050
|
}
|
|
1023
1051
|
function et() {
|
|
1024
|
-
return
|
|
1052
|
+
return S(P(16));
|
|
1025
1053
|
}
|
|
1026
|
-
const st =
|
|
1027
|
-
class
|
|
1054
|
+
const st = 6e4, it = 600 * 1e3;
|
|
1055
|
+
class ut {
|
|
1028
1056
|
constructor(t) {
|
|
1029
1057
|
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)
|
|
1030
1058
|
throw new r("invalid_config", "paywallId is required");
|
|
1031
|
-
|
|
1059
|
+
if (!t.apiOrigin)
|
|
1060
|
+
throw new r(
|
|
1061
|
+
"invalid_config",
|
|
1062
|
+
"apiOrigin is required. Pass the paywall custom_domain configured in the platform."
|
|
1063
|
+
);
|
|
1064
|
+
this.paywallId = t.paywallId, this.apiOrigin = t.apiOrigin, this.storage = C(t.storage), this.api = new E({
|
|
1032
1065
|
apiOrigin: this.apiOrigin,
|
|
1033
1066
|
paywallId: t.paywallId,
|
|
1034
1067
|
fetch: t.fetch
|
|
@@ -1054,14 +1087,15 @@ class dt {
|
|
|
1054
1087
|
async applyExternalSession(t) {
|
|
1055
1088
|
if (!this.destroyed && (await this.hydrated, !this.destroyed)) {
|
|
1056
1089
|
if (t == null) {
|
|
1057
|
-
this.session && this.setSession(null, { skipPersist: !0 });
|
|
1090
|
+
this.session && this.setSession(null, { skipPersist: !0, event: "SIGNED_OUT" });
|
|
1058
1091
|
return;
|
|
1059
1092
|
}
|
|
1060
1093
|
try {
|
|
1061
1094
|
const e = JSON.parse(t);
|
|
1062
1095
|
if (!e || typeof e.access_token != "string" || typeof e.refresh_token != "string" || typeof e.expires_at != "number" || !e.user)
|
|
1063
1096
|
return;
|
|
1064
|
-
this.
|
|
1097
|
+
const s = !this.session || this.session.user.id !== e.user.id ? "SIGNED_IN" : "TOKEN_REFRESHED";
|
|
1098
|
+
this.setSession(e, { skipPersist: !0, event: s });
|
|
1065
1099
|
} catch {
|
|
1066
1100
|
}
|
|
1067
1101
|
}
|
|
@@ -1105,7 +1139,7 @@ class dt {
|
|
|
1105
1139
|
await this.hydrated;
|
|
1106
1140
|
const e = await this.readVisitorId(), s = {};
|
|
1107
1141
|
t.idempotencyKey && (s["Idempotency-Key"] = t.idempotencyKey);
|
|
1108
|
-
const
|
|
1142
|
+
const a = await this.api.request(
|
|
1109
1143
|
`/api/v1/paywall/${this.paywallId}/auth/email/signin`,
|
|
1110
1144
|
{
|
|
1111
1145
|
method: "POST",
|
|
@@ -1117,8 +1151,8 @@ class dt {
|
|
|
1117
1151
|
user_meta: t.userMeta
|
|
1118
1152
|
})
|
|
1119
1153
|
}
|
|
1120
|
-
), n = this.toSession(
|
|
1121
|
-
return this.setSession(n), n;
|
|
1154
|
+
), n = this.toSession(a, a.user);
|
|
1155
|
+
return this.setSession(n, { event: "SIGNED_IN" }), n;
|
|
1122
1156
|
}
|
|
1123
1157
|
/**
|
|
1124
1158
|
* Signup. Если в Supabase включён email confirm — сервер возвращает
|
|
@@ -1130,7 +1164,7 @@ class dt {
|
|
|
1130
1164
|
await this.hydrated;
|
|
1131
1165
|
const e = await this.readVisitorId(), s = {};
|
|
1132
1166
|
t.idempotencyKey && (s["Idempotency-Key"] = t.idempotencyKey);
|
|
1133
|
-
const
|
|
1167
|
+
const a = await this.api.request(
|
|
1134
1168
|
`/api/v1/paywall/${this.paywallId}/auth/email/signup`,
|
|
1135
1169
|
{
|
|
1136
1170
|
method: "POST",
|
|
@@ -1143,10 +1177,10 @@ class dt {
|
|
|
1143
1177
|
})
|
|
1144
1178
|
}
|
|
1145
1179
|
);
|
|
1146
|
-
if (
|
|
1147
|
-
return { kind: "confirmation_required", user:
|
|
1148
|
-
const n = this.toSession(
|
|
1149
|
-
return this.setSession(n), { kind: "signed_in", session: n };
|
|
1180
|
+
if (a.status === "confirmation_required")
|
|
1181
|
+
return { kind: "confirmation_required", user: a.user };
|
|
1182
|
+
const n = this.toSession(a, a.user);
|
|
1183
|
+
return this.setSession(n, { event: "SIGNED_IN" }), { kind: "signed_in", session: n };
|
|
1150
1184
|
}
|
|
1151
1185
|
/**
|
|
1152
1186
|
* Повторная отправка confirmation-email после signUp с включённым
|
|
@@ -1209,8 +1243,8 @@ class dt {
|
|
|
1209
1243
|
user_meta: t.userMeta
|
|
1210
1244
|
})
|
|
1211
1245
|
}
|
|
1212
|
-
),
|
|
1213
|
-
return this.setSession(
|
|
1246
|
+
), a = this.toSession(s, s.user), n = t.type === "recovery" ? "PASSWORD_RECOVERY" : "SIGNED_IN";
|
|
1247
|
+
return this.setSession(a, { event: n }), a;
|
|
1214
1248
|
}
|
|
1215
1249
|
/**
|
|
1216
1250
|
* Запрос recovery email. Бэк всегда ok, чтобы не палить enumeration.
|
|
@@ -1297,12 +1331,12 @@ class dt {
|
|
|
1297
1331
|
user_meta: t.userMeta
|
|
1298
1332
|
})
|
|
1299
1333
|
}
|
|
1300
|
-
),
|
|
1334
|
+
), a = {
|
|
1301
1335
|
...s.user,
|
|
1302
1336
|
email: s.user.email ?? null,
|
|
1303
1337
|
is_anonymous: !0
|
|
1304
|
-
}, n = this.toSession(s,
|
|
1305
|
-
return this.setSession(n), await this.writeAnonRefreshToken(n.refresh_token), n;
|
|
1338
|
+
}, n = this.toSession(s, a);
|
|
1339
|
+
return this.setSession(n, { event: "SIGNED_IN" }), await this.writeAnonRefreshToken(n.refresh_token), n;
|
|
1306
1340
|
})();
|
|
1307
1341
|
try {
|
|
1308
1342
|
return await this.inflightAnonSignin;
|
|
@@ -1323,8 +1357,8 @@ class dt {
|
|
|
1323
1357
|
const e = await this.api.request(
|
|
1324
1358
|
`/api/v1/paywall/${this.paywallId}/auth/refresh`,
|
|
1325
1359
|
{ method: "POST", body: JSON.stringify({ refresh_token: t }) }
|
|
1326
|
-
), s = this.session?.user.is_anonymous === !0 ? this.session.user : { id: "", email: null, is_anonymous: !0 },
|
|
1327
|
-
return this.setSession(
|
|
1360
|
+
), s = this.session?.user.is_anonymous === !0 ? this.session.user : { id: "", email: null, is_anonymous: !0 }, a = this.toSession(e, s);
|
|
1361
|
+
return this.setSession(a, { event: "SIGNED_IN" }), await this.writeAnonRefreshToken(a.refresh_token), a;
|
|
1328
1362
|
} catch (e) {
|
|
1329
1363
|
if (e instanceof r && e.status === 401)
|
|
1330
1364
|
return await this.clearAnonRefreshToken(), null;
|
|
@@ -1361,7 +1395,7 @@ class dt {
|
|
|
1361
1395
|
Authorization: `Bearer ${e}`
|
|
1362
1396
|
};
|
|
1363
1397
|
t.idempotencyKey && (s["Idempotency-Key"] = t.idempotencyKey);
|
|
1364
|
-
const
|
|
1398
|
+
const a = await this.api.request(
|
|
1365
1399
|
`/api/v1/paywall/${this.paywallId}/auth/anonymous/upgrade`,
|
|
1366
1400
|
{
|
|
1367
1401
|
method: "POST",
|
|
@@ -1373,8 +1407,8 @@ class dt {
|
|
|
1373
1407
|
})
|
|
1374
1408
|
}
|
|
1375
1409
|
);
|
|
1376
|
-
if (
|
|
1377
|
-
return { kind: "confirmation_required", email:
|
|
1410
|
+
if (a.status === "confirmation_required")
|
|
1411
|
+
return { kind: "confirmation_required", email: a.email };
|
|
1378
1412
|
const n = this.session;
|
|
1379
1413
|
if (!n)
|
|
1380
1414
|
throw new r(
|
|
@@ -1383,11 +1417,11 @@ class dt {
|
|
|
1383
1417
|
);
|
|
1384
1418
|
const o = {
|
|
1385
1419
|
...n.user,
|
|
1386
|
-
id:
|
|
1387
|
-
email:
|
|
1388
|
-
is_anonymous:
|
|
1420
|
+
id: a.user.id,
|
|
1421
|
+
email: a.user.email,
|
|
1422
|
+
is_anonymous: a.user.is_anonymous ?? !1
|
|
1389
1423
|
}, u = { ...n, user: o };
|
|
1390
|
-
return this.setSession(u), await this.clearAnonRefreshToken(), { kind: "updated", session: u };
|
|
1424
|
+
return this.setSession(u, { event: "USER_UPDATED" }), await this.clearAnonRefreshToken(), { kind: "updated", session: u };
|
|
1391
1425
|
}
|
|
1392
1426
|
/**
|
|
1393
1427
|
* OAuth signin через popup с PKCE. Жизненный цикл:
|
|
@@ -1416,14 +1450,14 @@ class dt {
|
|
|
1416
1450
|
provider: t.provider,
|
|
1417
1451
|
scopes: t.scopes,
|
|
1418
1452
|
userMeta: t.userMeta
|
|
1419
|
-
}),
|
|
1420
|
-
if (!
|
|
1453
|
+
}), a = this.openPopup(e, `pw-oauth-${s}`);
|
|
1454
|
+
if (!a)
|
|
1421
1455
|
throw this.oauthFlows.delete(s), new r(
|
|
1422
1456
|
"popup_blocked",
|
|
1423
1457
|
"browser blocked auth popup — call from a user gesture"
|
|
1424
1458
|
);
|
|
1425
1459
|
t.onPopupOpened?.();
|
|
1426
|
-
const n = await
|
|
1460
|
+
const n = await rt(a, s);
|
|
1427
1461
|
if (this.destroyed)
|
|
1428
1462
|
throw this.oauthFlows.delete(s), new r("aborted", "AuthClient destroyed mid-flow");
|
|
1429
1463
|
return this.completeOAuthFlow({ state: s, code: n });
|
|
@@ -1444,7 +1478,7 @@ class dt {
|
|
|
1444
1478
|
*/
|
|
1445
1479
|
async startOAuthFlow(t) {
|
|
1446
1480
|
await this.hydrated, this.gcOAuthFlows();
|
|
1447
|
-
const e = Z(), s = await tt(e),
|
|
1481
|
+
const e = Z(), s = await tt(e), a = et(), n = {}, o = await this.getAccessToken().catch(() => null);
|
|
1448
1482
|
o && (n.Authorization = `Bearer ${o}`);
|
|
1449
1483
|
const { authorize_url: u } = await this.api.request(
|
|
1450
1484
|
`/api/v1/paywall/${this.paywallId}/auth/oauth/init`,
|
|
@@ -1459,11 +1493,11 @@ class dt {
|
|
|
1459
1493
|
})
|
|
1460
1494
|
}
|
|
1461
1495
|
);
|
|
1462
|
-
return this.oauthFlows.set(
|
|
1496
|
+
return this.oauthFlows.set(a, {
|
|
1463
1497
|
verifier: e,
|
|
1464
1498
|
userMeta: t.userMeta,
|
|
1465
1499
|
startedAt: Date.now()
|
|
1466
|
-
}), { authorize_url: u, state:
|
|
1500
|
+
}), { authorize_url: u, state: a };
|
|
1467
1501
|
}
|
|
1468
1502
|
/**
|
|
1469
1503
|
* Шаг 2 OAuth split-API: обменивает code (полученный из popup) на session,
|
|
@@ -1483,7 +1517,7 @@ class dt {
|
|
|
1483
1517
|
"OAuth flow not found — start with startOAuthFlow first or check TTL"
|
|
1484
1518
|
);
|
|
1485
1519
|
this.oauthFlows.delete(t.state);
|
|
1486
|
-
const s = await this.readVisitorId(),
|
|
1520
|
+
const s = await this.readVisitorId(), a = await this.api.request(
|
|
1487
1521
|
`/api/v1/paywall/${this.paywallId}/auth/oauth/exchange`,
|
|
1488
1522
|
{
|
|
1489
1523
|
method: "POST",
|
|
@@ -1497,11 +1531,11 @@ class dt {
|
|
|
1497
1531
|
);
|
|
1498
1532
|
if (this.destroyed)
|
|
1499
1533
|
throw new r("aborted", "AuthClient destroyed mid-flow");
|
|
1500
|
-
const n = this.toSession(
|
|
1501
|
-
return this.setSession(n), n;
|
|
1534
|
+
const n = this.toSession(a, a.user);
|
|
1535
|
+
return this.setSession(n, { event: "SIGNED_IN" }), n;
|
|
1502
1536
|
}
|
|
1503
1537
|
gcOAuthFlows() {
|
|
1504
|
-
const t = Date.now() -
|
|
1538
|
+
const t = Date.now() - it;
|
|
1505
1539
|
for (const [e, s] of this.oauthFlows)
|
|
1506
1540
|
s.startedAt < t && this.oauthFlows.delete(e);
|
|
1507
1541
|
}
|
|
@@ -1526,11 +1560,11 @@ class dt {
|
|
|
1526
1560
|
method: "POST",
|
|
1527
1561
|
body: JSON.stringify({ refresh_token: t })
|
|
1528
1562
|
}
|
|
1529
|
-
),
|
|
1530
|
-
return this.setSession(
|
|
1563
|
+
), a = this.toSession(s, e);
|
|
1564
|
+
return this.setSession(a, { event: "TOKEN_REFRESHED" }), e.is_anonymous === !0 && await this.writeAnonRefreshToken(a.refresh_token), a;
|
|
1531
1565
|
} catch (s) {
|
|
1532
1566
|
if (s instanceof r && s.status === 401)
|
|
1533
|
-
return e.is_anonymous === !0 && await this.clearAnonRefreshToken(), this.setSession(null), null;
|
|
1567
|
+
return e.is_anonymous === !0 && await this.clearAnonRefreshToken(), this.setSession(null, { event: "SIGNED_OUT" }), null;
|
|
1534
1568
|
throw s;
|
|
1535
1569
|
} finally {
|
|
1536
1570
|
this.inflightRefresh = null;
|
|
@@ -1563,7 +1597,7 @@ class dt {
|
|
|
1563
1597
|
method: "POST",
|
|
1564
1598
|
headers: { Authorization: `Bearer ${t}` }
|
|
1565
1599
|
}
|
|
1566
|
-
), this.setSession(null);
|
|
1600
|
+
), this.setSession(null, { event: "SIGNED_OUT" });
|
|
1567
1601
|
}
|
|
1568
1602
|
/**
|
|
1569
1603
|
* Signout: чистит локальную session СРАЗУ (UX — мгновенный logout без
|
|
@@ -1583,7 +1617,7 @@ class dt {
|
|
|
1583
1617
|
async signOut(t = {}) {
|
|
1584
1618
|
await this.hydrated;
|
|
1585
1619
|
const e = this.session?.access_token, s = this.session?.user.is_anonymous === !0;
|
|
1586
|
-
if (this.setSession(null), t.forgetAnonymous && await this.clearAnonRefreshToken(), !!e && !(s && !t.forgetAnonymous))
|
|
1620
|
+
if (this.setSession(null, { event: "SIGNED_OUT" }), t.forgetAnonymous && await this.clearAnonRefreshToken(), !!e && !(s && !t.forgetAnonymous))
|
|
1587
1621
|
try {
|
|
1588
1622
|
await this.api.request(
|
|
1589
1623
|
`/api/v1/paywall/${this.paywallId}/auth/signout`,
|
|
@@ -1597,22 +1631,35 @@ class dt {
|
|
|
1597
1631
|
}
|
|
1598
1632
|
/**
|
|
1599
1633
|
* Подписка на изменения session: signin/signup/refresh/signOut/expired-401.
|
|
1600
|
-
*
|
|
1601
|
-
*
|
|
1634
|
+
*
|
|
1635
|
+
* Гарантированный контракт: ПЕРВЫЙ callback каждому subscriber'у — всегда
|
|
1636
|
+
* `event = 'INITIAL_SESSION'`, дёргается асинхронно после resolve hydrate'а
|
|
1637
|
+
* (даже если session=null — listener получает explicit «нет сессии», а не
|
|
1638
|
+
* молчание). Все последующие callback'и — реальные переходы с конкретным
|
|
1639
|
+
* event'ом (SIGNED_IN / SIGNED_OUT / TOKEN_REFRESHED / USER_UPDATED /
|
|
1640
|
+
* PASSWORD_RECOVERY).
|
|
1641
|
+
*
|
|
1642
|
+
* Это позволяет listener'у безопасно делать «only on real signin» побочные
|
|
1643
|
+
* эффекты (force refetch balances и т.п.) через `event === 'SIGNED_IN'`,
|
|
1644
|
+
* не путая их с восстановлением из storage.
|
|
1645
|
+
*
|
|
1646
|
+
* Возвращает unsubscribe.
|
|
1602
1647
|
*/
|
|
1603
1648
|
onAuthChange(t) {
|
|
1604
|
-
|
|
1649
|
+
return this.listeners.add(t), this.hydrated.then(() => {
|
|
1650
|
+
if (this.destroyed || !this.listeners.has(t)) return;
|
|
1605
1651
|
const e = this.session;
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
})
|
|
1609
|
-
|
|
1610
|
-
|
|
1652
|
+
try {
|
|
1653
|
+
t("INITIAL_SESSION", e);
|
|
1654
|
+
} catch (s) {
|
|
1655
|
+
console.warn("[paywall] onAuthChange INITIAL_SESSION threw", s);
|
|
1656
|
+
}
|
|
1657
|
+
}), () => {
|
|
1611
1658
|
this.listeners.delete(t);
|
|
1612
1659
|
};
|
|
1613
1660
|
}
|
|
1614
1661
|
isFresh(t) {
|
|
1615
|
-
return t.expires_at - Date.now() >
|
|
1662
|
+
return t.expires_at - Date.now() > st;
|
|
1616
1663
|
}
|
|
1617
1664
|
toSession(t, e) {
|
|
1618
1665
|
const s = t.expires_at != null ? t.expires_at * 1e3 : Date.now() + t.expires_in * 1e3;
|
|
@@ -1623,17 +1670,17 @@ class dt {
|
|
|
1623
1670
|
user: e
|
|
1624
1671
|
};
|
|
1625
1672
|
}
|
|
1626
|
-
setSession(t, e
|
|
1673
|
+
setSession(t, e) {
|
|
1627
1674
|
if (this.destroyed) return;
|
|
1628
1675
|
const s = this.session;
|
|
1629
|
-
this.session = t, e.skipPersist || this.persist(),
|
|
1676
|
+
this.session = t, e.skipPersist || this.persist(), ot(s, t) || this.emit(e.event);
|
|
1630
1677
|
}
|
|
1631
|
-
emit() {
|
|
1632
|
-
for (const
|
|
1678
|
+
emit(t) {
|
|
1679
|
+
for (const e of this.listeners)
|
|
1633
1680
|
try {
|
|
1634
|
-
t
|
|
1635
|
-
} catch (
|
|
1636
|
-
console.warn("[paywall] onAuthChange listener threw",
|
|
1681
|
+
e(t, this.session);
|
|
1682
|
+
} catch (s) {
|
|
1683
|
+
console.warn("[paywall] onAuthChange listener threw", s);
|
|
1637
1684
|
}
|
|
1638
1685
|
}
|
|
1639
1686
|
storageKey() {
|
|
@@ -1646,7 +1693,7 @@ class dt {
|
|
|
1646
1693
|
const e = JSON.parse(t);
|
|
1647
1694
|
if (!e || typeof e.access_token != "string" || typeof e.refresh_token != "string" || typeof e.expires_at != "number" || !e.user)
|
|
1648
1695
|
return;
|
|
1649
|
-
this.session = e
|
|
1696
|
+
this.session = e;
|
|
1650
1697
|
} catch {
|
|
1651
1698
|
}
|
|
1652
1699
|
}
|
|
@@ -1660,7 +1707,7 @@ class dt {
|
|
|
1660
1707
|
const e = JSON.parse(t);
|
|
1661
1708
|
if (!e || typeof e.access_token != "string" || typeof e.refresh_token != "string" || typeof e.expires_at != "number" || !e.user)
|
|
1662
1709
|
return;
|
|
1663
|
-
this.setSession(e, { skipPersist: !0 });
|
|
1710
|
+
this.setSession(e, { skipPersist: !0, event: "SIGNED_IN" });
|
|
1664
1711
|
} catch {
|
|
1665
1712
|
}
|
|
1666
1713
|
}
|
|
@@ -1730,27 +1777,27 @@ class dt {
|
|
|
1730
1777
|
}
|
|
1731
1778
|
}
|
|
1732
1779
|
}
|
|
1733
|
-
const
|
|
1734
|
-
function
|
|
1780
|
+
const at = 5 * 6e4, nt = 500;
|
|
1781
|
+
function rt(i, t) {
|
|
1735
1782
|
return new Promise((e, s) => {
|
|
1736
|
-
let
|
|
1783
|
+
let a = !1;
|
|
1737
1784
|
const n = () => {
|
|
1738
|
-
|
|
1785
|
+
a = !0, window.removeEventListener("message", o), clearInterval(u), clearTimeout(l);
|
|
1739
1786
|
}, o = (d) => {
|
|
1740
|
-
if (
|
|
1787
|
+
if (a) return;
|
|
1741
1788
|
const h = d.data;
|
|
1742
1789
|
if (!(!h || h.type !== "pw-oauth") && h.messageId === t) {
|
|
1743
1790
|
if (h.status === "success" && h.code) {
|
|
1744
1791
|
n();
|
|
1745
1792
|
try {
|
|
1746
|
-
|
|
1793
|
+
i.close();
|
|
1747
1794
|
} catch {
|
|
1748
1795
|
}
|
|
1749
1796
|
e(h.code);
|
|
1750
1797
|
} else if (h.status === "error") {
|
|
1751
1798
|
n();
|
|
1752
1799
|
try {
|
|
1753
|
-
|
|
1800
|
+
i.close();
|
|
1754
1801
|
} catch {
|
|
1755
1802
|
}
|
|
1756
1803
|
s(
|
|
@@ -1762,32 +1809,32 @@ function ot(a, t) {
|
|
|
1762
1809
|
}
|
|
1763
1810
|
}
|
|
1764
1811
|
}, u = setInterval(() => {
|
|
1765
|
-
if (
|
|
1812
|
+
if (a) return;
|
|
1766
1813
|
let d;
|
|
1767
1814
|
try {
|
|
1768
|
-
d =
|
|
1815
|
+
d = i.closed;
|
|
1769
1816
|
} catch {
|
|
1770
1817
|
return;
|
|
1771
1818
|
}
|
|
1772
1819
|
d && (n(), s(new r("oauth_cancelled", "auth popup was closed")));
|
|
1773
|
-
},
|
|
1774
|
-
if (!
|
|
1820
|
+
}, nt), l = setTimeout(() => {
|
|
1821
|
+
if (!a) {
|
|
1775
1822
|
n();
|
|
1776
1823
|
try {
|
|
1777
|
-
|
|
1824
|
+
i.close();
|
|
1778
1825
|
} catch {
|
|
1779
1826
|
}
|
|
1780
1827
|
s(new r("oauth_timeout", "OAuth flow timed out"));
|
|
1781
1828
|
}
|
|
1782
|
-
},
|
|
1829
|
+
}, at);
|
|
1783
1830
|
window.addEventListener("message", o);
|
|
1784
1831
|
});
|
|
1785
1832
|
}
|
|
1786
|
-
function
|
|
1787
|
-
return
|
|
1833
|
+
function ot(i, t) {
|
|
1834
|
+
return i === t ? !0 : !i || !t ? !1 : i.access_token === t.access_token && i.refresh_token === t.refresh_token && i.expires_at === t.expires_at && i.user.id === t.user.id && i.user.email === t.user.email;
|
|
1788
1835
|
}
|
|
1789
|
-
const
|
|
1790
|
-
class
|
|
1836
|
+
const ht = 1500, ct = 20, k = 200;
|
|
1837
|
+
class dt {
|
|
1791
1838
|
constructor(t) {
|
|
1792
1839
|
this.buffer = [], this.flushTimer = null, this.destroyed = !1, this.unloadHandler = null, this.visibilityHandler = null, this.opts = t, this.isEnabled() && this.attachUnloadHandlers();
|
|
1793
1840
|
}
|
|
@@ -1797,7 +1844,7 @@ class ft {
|
|
|
1797
1844
|
track(t, e) {
|
|
1798
1845
|
if (this.destroyed || !this.isEnabled() || typeof t != "string" || t.length === 0) return;
|
|
1799
1846
|
this.buffer.push({ type: t, ts: Date.now(), props: e });
|
|
1800
|
-
const s = this.opts.maxBufferSize ??
|
|
1847
|
+
const s = this.opts.maxBufferSize ?? ct;
|
|
1801
1848
|
if (this.buffer.length >= s) {
|
|
1802
1849
|
this.flush();
|
|
1803
1850
|
return;
|
|
@@ -1806,7 +1853,7 @@ class ft {
|
|
|
1806
1853
|
}
|
|
1807
1854
|
scheduleFlush() {
|
|
1808
1855
|
if (this.flushTimer || this.destroyed) return;
|
|
1809
|
-
const t = this.opts.flushIntervalMs ??
|
|
1856
|
+
const t = this.opts.flushIntervalMs ?? ht;
|
|
1810
1857
|
this.flushTimer = setTimeout(() => {
|
|
1811
1858
|
this.flushTimer = null, this.flush();
|
|
1812
1859
|
}, t);
|
|
@@ -1817,7 +1864,7 @@ class ft {
|
|
|
1817
1864
|
const t = this.buffer;
|
|
1818
1865
|
this.buffer = [];
|
|
1819
1866
|
try {
|
|
1820
|
-
const e = await this.opts.getVisitorId(), s = this.opts.getUserId?.() ?? null,
|
|
1867
|
+
const e = await this.opts.getVisitorId(), s = this.opts.getUserId?.() ?? null, a = JSON.stringify({ events: t }), n = this.opts.fetch ?? (typeof fetch < "u" ? fetch : void 0);
|
|
1821
1868
|
if (!n) return;
|
|
1822
1869
|
await n(this.opts.endpoint, {
|
|
1823
1870
|
method: "POST",
|
|
@@ -1825,7 +1872,7 @@ class ft {
|
|
|
1825
1872
|
keepalive: !0,
|
|
1826
1873
|
// если страница закроется в этот момент — браузер всё равно дотянет
|
|
1827
1874
|
headers: this.buildHeaders(e, s),
|
|
1828
|
-
body:
|
|
1875
|
+
body: a
|
|
1829
1876
|
});
|
|
1830
1877
|
} catch {
|
|
1831
1878
|
}
|
|
@@ -1845,7 +1892,7 @@ class ft {
|
|
|
1845
1892
|
this.buffer.unshift(...t), this.flush();
|
|
1846
1893
|
return;
|
|
1847
1894
|
}
|
|
1848
|
-
const
|
|
1895
|
+
const a = JSON.stringify({
|
|
1849
1896
|
events: t,
|
|
1850
1897
|
// body-level дубликаты для beacon-flow, читаются сервером как fallback.
|
|
1851
1898
|
visitor_id: e,
|
|
@@ -1859,7 +1906,7 @@ class ft {
|
|
|
1859
1906
|
return;
|
|
1860
1907
|
}
|
|
1861
1908
|
try {
|
|
1862
|
-
n(this.opts.endpoint,
|
|
1909
|
+
n(this.opts.endpoint, a) || (this.buffer.unshift(...t), this.flush());
|
|
1863
1910
|
} catch {
|
|
1864
1911
|
this.buffer.unshift(...t), this.flush();
|
|
1865
1912
|
}
|
|
@@ -1886,17 +1933,17 @@ class ft {
|
|
|
1886
1933
|
}
|
|
1887
1934
|
}
|
|
1888
1935
|
export {
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1936
|
+
E as ApiClient,
|
|
1937
|
+
q as ApiGatewayClient,
|
|
1938
|
+
ut as AuthClient,
|
|
1939
|
+
lt as BillingClient,
|
|
1940
|
+
dt as EventTracker,
|
|
1894
1941
|
r as PaywallError,
|
|
1895
|
-
|
|
1942
|
+
D as QuotaExceededError,
|
|
1896
1943
|
m as SDK_VERSION,
|
|
1897
1944
|
y as STORAGE_KEYS,
|
|
1898
1945
|
C as createStorage,
|
|
1899
|
-
|
|
1900
|
-
|
|
1946
|
+
I as ensureVisitorId,
|
|
1947
|
+
N as generateVisitorId
|
|
1901
1948
|
};
|
|
1902
1949
|
//# sourceMappingURL=core.js.map
|