@palbase/web 1.7.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{analytics-facade-9GPSKnVG.d.cts → analytics-facade-DFd5LB3_.d.cts} +190 -5
- package/dist/{analytics-facade-CQJ3b-zB.d.ts → analytics-facade-DsvKx5A5.d.ts} +190 -5
- package/dist/{chunk-QRO632M7.js → chunk-I3ZMB7XM.js} +632 -21
- package/dist/chunk-I3ZMB7XM.js.map +1 -0
- package/dist/index.cjs +99 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -1
- package/dist/internal.cjs +631 -20
- package/dist/internal.cjs.map +1 -1
- package/dist/internal.d.cts +3 -3
- package/dist/internal.d.ts +3 -3
- package/dist/internal.js +1 -1
- package/dist/next/client.cjs +621 -17
- package/dist/next/client.cjs.map +1 -1
- package/dist/next/client.js +1 -1
- package/dist/next/index.cjs +627 -17
- package/dist/next/index.cjs.map +1 -1
- package/dist/next/index.d.cts +2 -2
- package/dist/next/index.d.ts +2 -2
- package/dist/next/index.js +1 -1
- package/dist/{pb-BvfCJZux.d.ts → pb-CDVMy1l1.d.ts} +9 -1
- package/dist/{pb-D4HyUbpb.d.cts → pb-D_fuhafL.d.cts} +9 -1
- package/dist/react/index.cjs +69 -13
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +1 -1
- package/dist/react/index.d.ts +1 -1
- package/dist/react/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-QRO632M7.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -161,14 +161,47 @@ function unwrap(res) {
|
|
|
161
161
|
return res.data;
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
+
// src/perf/url-redactor.ts
|
|
165
|
+
var ID_SEGMENT = /^(?:\d+|[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$/;
|
|
166
|
+
var EMAIL_SEGMENT = /(?:@|%40)/i;
|
|
167
|
+
function isSensitiveSegment(seg2) {
|
|
168
|
+
return ID_SEGMENT.test(seg2) || EMAIL_SEGMENT.test(seg2);
|
|
169
|
+
}
|
|
170
|
+
function redactUrl(rawUrl) {
|
|
171
|
+
let path = rawUrl;
|
|
172
|
+
try {
|
|
173
|
+
path = new URL(rawUrl).pathname;
|
|
174
|
+
} catch {
|
|
175
|
+
const q = path.indexOf("?");
|
|
176
|
+
if (q >= 0) path = path.slice(0, q);
|
|
177
|
+
}
|
|
178
|
+
return path.split("/").map((seg2) => isSensitiveSegment(seg2) ? ":id" : seg2).join("/");
|
|
179
|
+
}
|
|
180
|
+
|
|
164
181
|
// src/request.ts
|
|
165
182
|
var MUTATING = /* @__PURE__ */ new Set(["POST", "PUT", "PATCH", "DELETE"]);
|
|
183
|
+
var PERF_EXCLUDED_PREFIX = "/v1/analytics/";
|
|
184
|
+
function isSelfTraced(path) {
|
|
185
|
+
return path.startsWith(PERF_EXCLUDED_PREFIX);
|
|
186
|
+
}
|
|
187
|
+
function nowMs() {
|
|
188
|
+
return typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
|
|
189
|
+
}
|
|
190
|
+
function isAbort(e) {
|
|
191
|
+
return e instanceof Error && e.name === "AbortError";
|
|
192
|
+
}
|
|
166
193
|
async function palbeRequest(rt, method, path, spec = {}) {
|
|
167
194
|
const headers = { ...spec.headers };
|
|
168
195
|
const callerHasKey = Object.keys(headers).some((k) => k.toLowerCase() === "idempotency-key");
|
|
169
196
|
if (MUTATING.has(method) && !callerHasKey) {
|
|
170
197
|
headers["Idempotency-Key"] = crypto.randomUUID();
|
|
171
198
|
}
|
|
199
|
+
if (rt.appIdentifier !== "") {
|
|
200
|
+
const callerHasBundle = Object.keys(headers).some(
|
|
201
|
+
(k) => k.toLowerCase() === "x-palbase-bundle"
|
|
202
|
+
);
|
|
203
|
+
if (!callerHasBundle) headers["X-Palbase-Bundle"] = rt.appIdentifier;
|
|
204
|
+
}
|
|
172
205
|
const attempt = async () => {
|
|
173
206
|
try {
|
|
174
207
|
return await rt.http.request(method, path, {
|
|
@@ -181,21 +214,38 @@ async function palbeRequest(rt, method, path, spec = {}) {
|
|
|
181
214
|
throw pe ? fromPalbaseError(pe) : e;
|
|
182
215
|
}
|
|
183
216
|
};
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
217
|
+
const traced = !isSelfTraced(path) && rt.perf !== void 0;
|
|
218
|
+
const startedAt = traced ? nowMs() : 0;
|
|
219
|
+
let recorded = false;
|
|
220
|
+
const record = (status) => {
|
|
221
|
+
if (!traced || recorded) return;
|
|
222
|
+
recorded = true;
|
|
223
|
+
rt.perf.recordNetwork(method, redactUrl(path), status, nowMs() - startedAt);
|
|
224
|
+
};
|
|
225
|
+
let res;
|
|
226
|
+
try {
|
|
227
|
+
res = await attempt();
|
|
228
|
+
if (res.error?.status === 401 && rt.tokenManager.getRefreshToken() && rt.tokenManager.refreshFunction) {
|
|
229
|
+
try {
|
|
230
|
+
await rt.tokenManager.refreshSession();
|
|
231
|
+
} catch (refreshErr) {
|
|
232
|
+
const pe = asPalbaseError(refreshErr);
|
|
233
|
+
const status = pe?.status ?? 0;
|
|
234
|
+
if (status === 400 || status === 401 || status === 403) {
|
|
235
|
+
rt.tokenManager.clearSession();
|
|
236
|
+
record(res.error.status);
|
|
237
|
+
throw fromPalbaseError(res.error);
|
|
238
|
+
}
|
|
239
|
+
record(pe?.status ?? 0);
|
|
240
|
+
throw pe ? fromPalbaseError(pe) : refreshErr;
|
|
194
241
|
}
|
|
195
|
-
|
|
242
|
+
res = await attempt();
|
|
196
243
|
}
|
|
197
|
-
|
|
244
|
+
} catch (e) {
|
|
245
|
+
if (!isAbort(e)) record(asPalbaseError(e)?.status ?? 0);
|
|
246
|
+
throw e;
|
|
198
247
|
}
|
|
248
|
+
record(res.error?.status ?? 200);
|
|
199
249
|
return unwrap(res);
|
|
200
250
|
}
|
|
201
251
|
|
|
@@ -439,6 +489,8 @@ var PalbeAuth = class {
|
|
|
439
489
|
// suppresses AuthClient's TOKEN_REFRESHED during re-signIn
|
|
440
490
|
signedInState = false;
|
|
441
491
|
// dedupes AuthClient's repeated SIGNED_OUT events
|
|
492
|
+
hydratingUser = false;
|
|
493
|
+
// guards hydrateUser() to a single boot fetch
|
|
442
494
|
stateListeners = /* @__PURE__ */ new Set();
|
|
443
495
|
eventListeners = /* @__PURE__ */ new Set();
|
|
444
496
|
userListeners = /* @__PURE__ */ new Set();
|
|
@@ -491,13 +543,37 @@ var PalbeAuth = class {
|
|
|
491
543
|
if (changed) for (const cb of this.userListeners) this.safeInvoke(() => cb(user));
|
|
492
544
|
return user;
|
|
493
545
|
}
|
|
546
|
+
/**
|
|
547
|
+
* Restore the user after a session was rehydrated from storage (page reload).
|
|
548
|
+
* Hydration in buildRuntime restores the TOKENS synchronously, but the access
|
|
549
|
+
* token JWT does not carry emailVerified/createdAt, so the full AuthUser can't
|
|
550
|
+
* be reconstructed offline — this fetches GET /auth/user once and announces
|
|
551
|
+
* `signedIn`, so the app no longer has to `await pb.auth.refreshUser()` itself
|
|
552
|
+
* on boot. Idempotent (runs once), browser-safe (no-op when not signed in or
|
|
553
|
+
* a user is already cached), and never throws (a boot-time network failure
|
|
554
|
+
* must not break app startup — isSignedIn stays true, the app can retry).
|
|
555
|
+
*/
|
|
556
|
+
hydrateUser() {
|
|
557
|
+
if (this.hydratingUser || this.cachedUser || !this.isSignedIn) return;
|
|
558
|
+
this.hydratingUser = true;
|
|
559
|
+
void this.refreshUser().then((user) => {
|
|
560
|
+
if (this.isSignedIn) {
|
|
561
|
+
this.signedInState = true;
|
|
562
|
+
this.emitState({ status: "signedIn", user });
|
|
563
|
+
}
|
|
564
|
+
}).catch(() => {
|
|
565
|
+
}).finally(() => {
|
|
566
|
+
this.hydratingUser = false;
|
|
567
|
+
});
|
|
568
|
+
}
|
|
494
569
|
// ── listeners ──────────────────────────────────────────
|
|
495
570
|
/**
|
|
496
571
|
* Subscribe to signed-in/signed-out state. Fires immediately with the
|
|
497
|
-
* current snapshot (iOS parity).
|
|
498
|
-
*
|
|
499
|
-
*
|
|
500
|
-
*
|
|
572
|
+
* current snapshot (iOS parity). A restored session (page reload) hydrates
|
|
573
|
+
* the user asynchronously via `hydrateUser()` (fired once at boot), so the
|
|
574
|
+
* FIRST snapshot may report signedOut for a tick even when `isSignedIn` is
|
|
575
|
+
* true; the listener then fires again with `signedIn` once the user lands.
|
|
576
|
+
* Rely on `isSignedIn` for the session truth if you need it synchronously.
|
|
501
577
|
*/
|
|
502
578
|
onAuthStateChange(callback) {
|
|
503
579
|
this.stateListeners.add(callback);
|
|
@@ -7507,7 +7583,7 @@ function localStorageSessionStorage(key = DEFAULT_KEY) {
|
|
|
7507
7583
|
}
|
|
7508
7584
|
|
|
7509
7585
|
// src/version.ts
|
|
7510
|
-
var VERSION = "1.
|
|
7586
|
+
var VERSION = "1.9.0";
|
|
7511
7587
|
|
|
7512
7588
|
// src/internal.ts
|
|
7513
7589
|
function getRuntime() {
|
|
@@ -7676,6 +7752,12 @@ function createClientProxy(resolveRt, nsAccessor) {
|
|
|
7676
7752
|
},
|
|
7677
7753
|
get messaging() {
|
|
7678
7754
|
return resolveRt().messaging;
|
|
7755
|
+
},
|
|
7756
|
+
get perf() {
|
|
7757
|
+
return resolveRt().perf;
|
|
7758
|
+
},
|
|
7759
|
+
setTestDevice(on) {
|
|
7760
|
+
resolveRt().perf.setTestDevice(on);
|
|
7679
7761
|
}
|
|
7680
7762
|
};
|
|
7681
7763
|
return new Proxy(base, {
|