@palbase/web 1.6.2 → 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.
@@ -1,6 +1,6 @@
1
1
  import { NextRequest, NextResponse } from 'next/server';
2
- import { P as PB } from '../pb-VzJvX7Gg.cjs';
3
- import '../analytics-facade-ATGUv2-f.cjs';
2
+ import { P as PB } from '../pb-BwQwp411.cjs';
3
+ import '../analytics-facade-DfJ420F5.cjs';
4
4
  import 'livekit-client';
5
5
  import '../storage-BPaeSG8K.cjs';
6
6
  import './pooled-flags-Bwq4usn0.js';
@@ -1,6 +1,6 @@
1
1
  import { NextRequest, NextResponse } from 'next/server';
2
- import { P as PB } from '../pb-TAUNVyT6.js';
3
- import '../analytics-facade-DhcTP_kw.js';
2
+ import { P as PB } from '../pb-C1v9ErPy.js';
3
+ import '../analytics-facade-CgURkjpP.js';
4
4
  import 'livekit-client';
5
5
  import '../storage-BPaeSG8K.js';
6
6
  import './pooled-flags-Bwq4usn0.js';
@@ -13,7 +13,7 @@ import {
13
13
  createBoundClient,
14
14
  endpointRefFromApiKey,
15
15
  getRuntime
16
- } from "../chunk-XQZ53URR.js";
16
+ } from "../chunk-AWVNDAMG.js";
17
17
 
18
18
  // src/next/shared.ts
19
19
  function requireGlobalConfig(hint) {
@@ -1,4 +1,4 @@
1
- import { t as PalbeAuth, w as PalbeFlags, z as PalbeRealtime, P as PalbeAnalytics, u as PalbeCalls, x as PalbeMessaging, N as PalbeRuntime } from './analytics-facade-ATGUv2-f.cjs';
1
+ import { t as PalbeAuth, w as PalbeFlags, z as PalbeRealtime, P as PalbeAnalytics, u as PalbeCalls, x as PalbeMessaging, W as PalbePerf, T as PalbeRuntime } from './analytics-facade-DfJ420F5.cjs';
2
2
 
3
3
  interface CallOptions {
4
4
  headers?: Record<string, string>;
@@ -42,6 +42,14 @@ interface PB {
42
42
  readonly analytics: PalbeAnalytics;
43
43
  readonly calls: PalbeCalls;
44
44
  readonly messaging: PalbeMessaging;
45
+ /** The PalPerf surface: custom traces (`startTrace`) + the buffered flush of
46
+ * network/app-start/custom items. `pb.perf.record(...)` is also how the
47
+ * runtime feeds the cold-start measurement in. */
48
+ readonly perf: PalbePerf;
49
+ /** Mark (or unmark) this client's traffic as test — flips the facade's flag
50
+ * so every subsequent perf flush carries `X-Palbase-Test-Device: 1` (the
51
+ * SAME header the iOS SDK sends; the server reads it → `is_test_traffic`). */
52
+ setTestDevice(on: boolean): void;
45
53
  }
46
54
  declare const pb: PB;
47
55
  /**
@@ -1,4 +1,4 @@
1
- import { t as PalbeAuth, w as PalbeFlags, z as PalbeRealtime, P as PalbeAnalytics, u as PalbeCalls, x as PalbeMessaging, N as PalbeRuntime } from './analytics-facade-DhcTP_kw.js';
1
+ import { t as PalbeAuth, w as PalbeFlags, z as PalbeRealtime, P as PalbeAnalytics, u as PalbeCalls, x as PalbeMessaging, W as PalbePerf, T as PalbeRuntime } from './analytics-facade-CgURkjpP.js';
2
2
 
3
3
  interface CallOptions {
4
4
  headers?: Record<string, string>;
@@ -42,6 +42,14 @@ interface PB {
42
42
  readonly analytics: PalbeAnalytics;
43
43
  readonly calls: PalbeCalls;
44
44
  readonly messaging: PalbeMessaging;
45
+ /** The PalPerf surface: custom traces (`startTrace`) + the buffered flush of
46
+ * network/app-start/custom items. `pb.perf.record(...)` is also how the
47
+ * runtime feeds the cold-start measurement in. */
48
+ readonly perf: PalbePerf;
49
+ /** Mark (or unmark) this client's traffic as test — flips the facade's flag
50
+ * so every subsequent perf flush carries `X-Palbase-Test-Device: 1` (the
51
+ * SAME header the iOS SDK sends; the server reads it → `is_test_traffic`). */
52
+ setTestDevice(on: boolean): void;
45
53
  }
46
54
  declare const pb: PB;
47
55
  /**
@@ -152,14 +152,47 @@ function unwrap(res) {
152
152
  return res.data;
153
153
  }
154
154
 
155
+ // src/perf/url-redactor.ts
156
+ 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})$/;
157
+ var EMAIL_SEGMENT = /(?:@|%40)/i;
158
+ function isSensitiveSegment(seg) {
159
+ return ID_SEGMENT.test(seg) || EMAIL_SEGMENT.test(seg);
160
+ }
161
+ function redactUrl(rawUrl) {
162
+ let path = rawUrl;
163
+ try {
164
+ path = new URL(rawUrl).pathname;
165
+ } catch {
166
+ const q = path.indexOf("?");
167
+ if (q >= 0) path = path.slice(0, q);
168
+ }
169
+ return path.split("/").map((seg) => isSensitiveSegment(seg) ? ":id" : seg).join("/");
170
+ }
171
+
155
172
  // src/request.ts
156
173
  var MUTATING = /* @__PURE__ */ new Set(["POST", "PUT", "PATCH", "DELETE"]);
174
+ var PERF_EXCLUDED_PREFIX = "/v1/analytics/";
175
+ function isSelfTraced(path) {
176
+ return path.startsWith(PERF_EXCLUDED_PREFIX);
177
+ }
178
+ function nowMs() {
179
+ return typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
180
+ }
181
+ function isAbort(e) {
182
+ return e instanceof Error && e.name === "AbortError";
183
+ }
157
184
  async function palbeRequest(rt, method, path, spec = {}) {
158
185
  const headers = { ...spec.headers };
159
186
  const callerHasKey = Object.keys(headers).some((k) => k.toLowerCase() === "idempotency-key");
160
187
  if (MUTATING.has(method) && !callerHasKey) {
161
188
  headers["Idempotency-Key"] = crypto.randomUUID();
162
189
  }
190
+ if (rt.appIdentifier !== "") {
191
+ const callerHasBundle = Object.keys(headers).some(
192
+ (k) => k.toLowerCase() === "x-palbase-bundle"
193
+ );
194
+ if (!callerHasBundle) headers["X-Palbase-Bundle"] = rt.appIdentifier;
195
+ }
163
196
  const attempt = async () => {
164
197
  try {
165
198
  return await rt.http.request(method, path, {
@@ -172,21 +205,38 @@ async function palbeRequest(rt, method, path, spec = {}) {
172
205
  throw pe ? fromPalbaseError(pe) : e;
173
206
  }
174
207
  };
175
- let res = await attempt();
176
- if (res.error?.status === 401 && rt.tokenManager.getRefreshToken() && rt.tokenManager.refreshFunction) {
177
- try {
178
- await rt.tokenManager.refreshSession();
179
- } catch (refreshErr) {
180
- const pe = asPalbaseError(refreshErr);
181
- const status = pe?.status ?? 0;
182
- if (status === 400 || status === 401 || status === 403) {
183
- rt.tokenManager.clearSession();
184
- throw fromPalbaseError(res.error);
208
+ const traced = !isSelfTraced(path) && rt.perf !== void 0;
209
+ const startedAt = traced ? nowMs() : 0;
210
+ let recorded = false;
211
+ const record = (status) => {
212
+ if (!traced || recorded) return;
213
+ recorded = true;
214
+ rt.perf.recordNetwork(method, redactUrl(path), status, nowMs() - startedAt);
215
+ };
216
+ let res;
217
+ try {
218
+ res = await attempt();
219
+ if (res.error?.status === 401 && rt.tokenManager.getRefreshToken() && rt.tokenManager.refreshFunction) {
220
+ try {
221
+ await rt.tokenManager.refreshSession();
222
+ } catch (refreshErr) {
223
+ const pe = asPalbaseError(refreshErr);
224
+ const status = pe?.status ?? 0;
225
+ if (status === 400 || status === 401 || status === 403) {
226
+ rt.tokenManager.clearSession();
227
+ record(res.error.status);
228
+ throw fromPalbaseError(res.error);
229
+ }
230
+ record(pe?.status ?? 0);
231
+ throw pe ? fromPalbaseError(pe) : refreshErr;
185
232
  }
186
- throw pe ? fromPalbaseError(pe) : refreshErr;
233
+ res = await attempt();
187
234
  }
188
- res = await attempt();
235
+ } catch (e) {
236
+ if (!isAbort(e)) record(asPalbaseError(e)?.status ?? 0);
237
+ throw e;
189
238
  }
239
+ record(res.error?.status ?? 200);
190
240
  return unwrap(res);
191
241
  }
192
242
 
@@ -297,7 +347,7 @@ function getNamespace(name) {
297
347
  }
298
348
 
299
349
  // src/version.ts
300
- var VERSION = "1.6.2";
350
+ var VERSION = "1.8.0";
301
351
 
302
352
  // src/call.ts
303
353
  async function callEndpoint(resolveRt, name, input, options) {
@@ -476,6 +526,12 @@ function createClientProxy(resolveRt, nsAccessor) {
476
526
  },
477
527
  get messaging() {
478
528
  return resolveRt().messaging;
529
+ },
530
+ get perf() {
531
+ return resolveRt().perf;
532
+ },
533
+ setTestDevice(on) {
534
+ resolveRt().perf.setTestDevice(on);
479
535
  }
480
536
  };
481
537
  return new Proxy(base, {