@palbase/web 1.7.0 → 1.8.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/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
- let res = await attempt();
185
- if (res.error?.status === 401 && rt.tokenManager.getRefreshToken() && rt.tokenManager.refreshFunction) {
186
- try {
187
- await rt.tokenManager.refreshSession();
188
- } catch (refreshErr) {
189
- const pe = asPalbaseError(refreshErr);
190
- const status = pe?.status ?? 0;
191
- if (status === 400 || status === 401 || status === 403) {
192
- rt.tokenManager.clearSession();
193
- throw fromPalbaseError(res.error);
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
- throw pe ? fromPalbaseError(pe) : refreshErr;
242
+ res = await attempt();
196
243
  }
197
- res = await attempt();
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
 
@@ -7507,7 +7557,7 @@ function localStorageSessionStorage(key = DEFAULT_KEY) {
7507
7557
  }
7508
7558
 
7509
7559
  // src/version.ts
7510
- var VERSION = "1.7.0";
7560
+ var VERSION = "1.8.0";
7511
7561
 
7512
7562
  // src/internal.ts
7513
7563
  function getRuntime() {
@@ -7676,6 +7726,12 @@ function createClientProxy(resolveRt, nsAccessor) {
7676
7726
  },
7677
7727
  get messaging() {
7678
7728
  return resolveRt().messaging;
7729
+ },
7730
+ get perf() {
7731
+ return resolveRt().perf;
7732
+ },
7733
+ setTestDevice(on) {
7734
+ resolveRt().perf.setTestDevice(on);
7679
7735
  }
7680
7736
  };
7681
7737
  return new Proxy(base, {