@palbase/web 7.2.2 → 7.3.1

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.
Files changed (44) hide show
  1. package/dist/{analytics-facade-DLfnVVwL.d.ts → analytics-facade-BER0EyYT.d.ts} +8 -3
  2. package/dist/{analytics-facade-jyXv7Cu4.d.cts → analytics-facade-CQXCQSoF.d.cts} +8 -3
  3. package/dist/{chunk-ACCJV6FV.js → chunk-53TN7KYR.js} +58 -5
  4. package/dist/chunk-53TN7KYR.js.map +1 -0
  5. package/dist/{chunk-ZC6Q3GPX.js → chunk-CBN3PWNL.js} +2 -2
  6. package/dist/{chunk-IREKQSHT.js → chunk-RRHJV6YD.js} +22 -15
  7. package/dist/chunk-RRHJV6YD.js.map +1 -0
  8. package/dist/gen/cli.cjs +6 -12
  9. package/dist/gen/cli.cjs.map +1 -1
  10. package/dist/gen/cli.js +6 -12
  11. package/dist/gen/cli.js.map +1 -1
  12. package/dist/index.cjs +49 -4
  13. package/dist/index.cjs.map +1 -1
  14. package/dist/index.d.cts +3 -3
  15. package/dist/index.d.ts +3 -3
  16. package/dist/index.js +2 -2
  17. package/dist/internal.cjs +73 -17
  18. package/dist/internal.cjs.map +1 -1
  19. package/dist/internal.d.cts +3 -3
  20. package/dist/internal.d.ts +3 -3
  21. package/dist/internal.js +2 -2
  22. package/dist/next/client.cjs +81 -25
  23. package/dist/next/client.cjs.map +1 -1
  24. package/dist/next/client.js +6 -4
  25. package/dist/next/client.js.map +1 -1
  26. package/dist/next/index.cjs +87 -31
  27. package/dist/next/index.cjs.map +1 -1
  28. package/dist/next/index.d.cts +2 -22
  29. package/dist/next/index.d.ts +2 -22
  30. package/dist/next/index.js +7 -6
  31. package/dist/next/index.js.map +1 -1
  32. package/dist/next/proxy.js +2 -2
  33. package/dist/{pb-DdzpEkPY.d.ts → pb-BRlmBIAm.d.ts} +1 -1
  34. package/dist/{pb-CfYQGEn0.d.cts → pb-WAQvwCfM.d.cts} +1 -1
  35. package/dist/react/index.cjs +48 -3
  36. package/dist/react/index.cjs.map +1 -1
  37. package/dist/react/index.d.cts +1 -1
  38. package/dist/react/index.d.ts +1 -1
  39. package/dist/react/index.js +2 -2
  40. package/package.json +13 -13
  41. package/LICENSE +0 -21
  42. package/dist/chunk-ACCJV6FV.js.map +0 -1
  43. package/dist/chunk-IREKQSHT.js.map +0 -1
  44. /package/dist/{chunk-ZC6Q3GPX.js.map → chunk-CBN3PWNL.js.map} +0 -0
@@ -1,7 +1,7 @@
1
- import { P as PalbeConfig } from './analytics-facade-jyXv7Cu4.cjs';
2
- export { d as PalbeRuntime, e as buildRuntime } from './analytics-facade-jyXv7Cu4.cjs';
1
+ import { P as PalbeConfig } from './analytics-facade-CQXCQSoF.cjs';
2
+ export { d as PalbeRuntime, e as buildRuntime } from './analytics-facade-CQXCQSoF.cjs';
3
3
  import { B as BackendError } from './errors-fDoNdTrJ.cjs';
4
- export { P as PB, c as createBoundClient } from './pb-CfYQGEn0.cjs';
4
+ export { P as PB, c as createBoundClient } from './pb-WAQvwCfM.cjs';
5
5
  import './storage-BPaeSG8K.cjs';
6
6
  import './pooled-flags-4GtDtsiu.js';
7
7
 
@@ -1,7 +1,7 @@
1
- import { P as PalbeConfig } from './analytics-facade-DLfnVVwL.js';
2
- export { d as PalbeRuntime, e as buildRuntime } from './analytics-facade-DLfnVVwL.js';
1
+ import { P as PalbeConfig } from './analytics-facade-BER0EyYT.js';
2
+ export { d as PalbeRuntime, e as buildRuntime } from './analytics-facade-BER0EyYT.js';
3
3
  import { B as BackendError } from './errors-fDoNdTrJ.js';
4
- export { P as PB, c as createBoundClient } from './pb-DdzpEkPY.js';
4
+ export { P as PB, c as createBoundClient } from './pb-BRlmBIAm.js';
5
5
  import './storage-BPaeSG8K.js';
6
6
  import './pooled-flags-4GtDtsiu.js';
7
7
 
package/dist/internal.js CHANGED
@@ -6,8 +6,8 @@ import {
6
6
  createBoundClient,
7
7
  getRuntime,
8
8
  onConfigured
9
- } from "./chunk-IREKQSHT.js";
10
- import "./chunk-ACCJV6FV.js";
9
+ } from "./chunk-RRHJV6YD.js";
10
+ import "./chunk-53TN7KYR.js";
11
11
  import "./chunk-CFDU23TB.js";
12
12
  import "./chunk-PZ5AY32C.js";
13
13
  export {
@@ -35,6 +35,13 @@ __export(client_exports, {
35
35
  });
36
36
  module.exports = __toCommonJS(client_exports);
37
37
 
38
+ // src/api-key.ts
39
+ var PUBLISHABLE_API_KEY_RE = /^pb_([a-z0-9]{4,24})_c[A-Za-z0-9]{20}$/;
40
+ function environmentRefFromPublishableApiKey(apiKey) {
41
+ const match = PUBLISHABLE_API_KEY_RE.exec(apiKey);
42
+ return match ? match[1] ?? "" : "";
43
+ }
44
+
38
45
  // ../core/dist/index.js
39
46
  var CACHE_TTL_MS = 5 * 60 * 1e3;
40
47
  var PalbaseError = class extends Error {
@@ -49,6 +56,45 @@ var PalbaseError = class extends Error {
49
56
  this.details = details;
50
57
  }
51
58
  };
59
+ var POW_CHALLENGE_ID_HEADER = "X-PoW-Challenge-ID";
60
+ var POW_NONCE_HEADER = "X-PoW-Nonce";
61
+ function asPowChallenge(details) {
62
+ if (typeof details !== "object" || details === null) return null;
63
+ const env = details;
64
+ if (env.error !== "pow_required") return null;
65
+ const c = env.challenge;
66
+ if (typeof c !== "object" || c === null) return null;
67
+ const { id, prefix, difficulty } = c;
68
+ if (typeof id !== "string" || typeof prefix !== "string") return null;
69
+ if (typeof difficulty !== "number" || !Number.isInteger(difficulty) || difficulty < 0) return null;
70
+ return { id, prefix, difficulty };
71
+ }
72
+ var encoder = new TextEncoder();
73
+ function leadingZeroBits(hash) {
74
+ let bits = 0;
75
+ for (const byte of hash) {
76
+ if (byte === 0) {
77
+ bits += 8;
78
+ continue;
79
+ }
80
+ return bits + Math.clz32(byte) - 24;
81
+ }
82
+ return bits;
83
+ }
84
+ async function solvePowChallenge(challenge, maxIterations = 1 << 24) {
85
+ for (let nonce = 0; nonce < maxIterations; nonce++) {
86
+ const digest = await crypto.subtle.digest("SHA-256", encoder.encode(challenge.prefix + nonce));
87
+ if (leadingZeroBits(new Uint8Array(digest)) >= challenge.difficulty) {
88
+ return {
89
+ [POW_CHALLENGE_ID_HEADER]: challenge.id,
90
+ [POW_NONCE_HEADER]: String(nonce)
91
+ };
92
+ }
93
+ }
94
+ throw new Error(
95
+ `proof-of-work: no nonce found for difficulty ${challenge.difficulty} within ${maxIterations} attempts`
96
+ );
97
+ }
52
98
  function detectPlatform() {
53
99
  if (typeof Deno !== "undefined") {
54
100
  return "deno";
@@ -185,9 +231,9 @@ var HttpClient = class _HttpClient {
185
231
  }
186
232
  return headers;
187
233
  }
188
- async executeWithRetry(method, path, options, attempt) {
234
+ async executeWithRetry(method, path, options, attempt, earned) {
189
235
  const url = `${this.getBaseUrl()}${path}`;
190
- const headers = this.buildHeaders(options);
236
+ const headers = { ...this.buildHeaders(options), ...earned };
191
237
  for (const interceptor of this.interceptors) {
192
238
  await interceptor({ headers, method, path });
193
239
  }
@@ -206,7 +252,7 @@ var HttpClient = class _HttpClient {
206
252
  if (attempt < MAX_RETRIES - 1) {
207
253
  const backoff = INITIAL_BACKOFF_MS * 2 ** attempt;
208
254
  await this.delay(backoff);
209
- return this.executeWithRetry(method, path, options, attempt + 1);
255
+ return this.executeWithRetry(method, path, options, attempt + 1, earned);
210
256
  }
211
257
  throw new PalbaseError(
212
258
  "network_error",
@@ -220,7 +266,7 @@ var HttpClient = class _HttpClient {
220
266
  const parsed = retryAfter ? Number.parseInt(retryAfter, 10) : Number.NaN;
221
267
  const delayMs = Number.isNaN(parsed) ? INITIAL_BACKOFF_MS * 2 ** attempt : Math.min(parsed * 1e3, MAX_RETRY_DELAY_MS);
222
268
  await this.delay(delayMs);
223
- return this.executeWithRetry(method, path, options, attempt + 1);
269
+ return this.executeWithRetry(method, path, options, attempt + 1, earned);
224
270
  }
225
271
  }
226
272
  let data = null;
@@ -234,6 +280,18 @@ var HttpClient = class _HttpClient {
234
280
  errorBody = body;
235
281
  }
236
282
  }
283
+ if (response.status === 403 && !earned) {
284
+ const challenge = asPowChallenge(errorBody);
285
+ if (challenge) {
286
+ return this.executeWithRetry(
287
+ method,
288
+ path,
289
+ options,
290
+ attempt,
291
+ await solvePowChallenge(challenge)
292
+ );
293
+ }
294
+ }
237
295
  if (!response.ok) {
238
296
  return {
239
297
  data: null,
@@ -474,11 +532,11 @@ async function palbeRequest(rt, method, path, spec = {}) {
474
532
  if (MUTATING.has(method) && !callerHasKey) {
475
533
  headers["Idempotency-Key"] = crypto.randomUUID();
476
534
  }
477
- const attempt = async () => {
535
+ const attempt = async (extra) => {
478
536
  try {
479
537
  return await rt.http.request(method, path, {
480
538
  body: spec.body,
481
- headers,
539
+ headers: extra ? { ...headers, ...extra } : headers,
482
540
  signal: spec.signal
483
541
  });
484
542
  } catch (e) {
@@ -513,6 +571,12 @@ async function palbeRequest(rt, method, path, spec = {}) {
513
571
  }
514
572
  res = await attempt();
515
573
  }
574
+ if (res.error?.status === 403 && res.error.code === "pow_required") {
575
+ const challenge = asPowChallenge(res.error.details);
576
+ if (challenge) {
577
+ res = await attempt(await solvePowChallenge(challenge));
578
+ }
579
+ }
516
580
  } catch (e) {
517
581
  if (!isAbort(e)) record(asPalbaseError(e)?.status ?? 0);
518
582
  throw e;
@@ -1058,7 +1122,7 @@ var AnalyticsState = class {
1058
1122
  idKey;
1059
1123
  optOutKey;
1060
1124
  constructor(rt) {
1061
- const ref = rt.config.environmentRef;
1125
+ const ref = rt.projectRef;
1062
1126
  this.idKey = ref ? `palbe.analytics.id.${ref}` : "palbe.analytics.id";
1063
1127
  this.optOutKey = ref ? `palbe.analytics.optout.${ref}` : "palbe.analytics.optout";
1064
1128
  rt.auth.onAuthEvent((event) => {
@@ -1272,13 +1336,6 @@ var PalbeAnalytics = class {
1272
1336
  }
1273
1337
  };
1274
1338
 
1275
- // src/api-key.ts
1276
- var PUBLISHABLE_API_KEY_RE = /^pb_([a-z0-9]{4,24})_c[A-Za-z0-9]{20}$/;
1277
- function environmentRefFromPublishableApiKey(apiKey) {
1278
- const match = PUBLISHABLE_API_KEY_RE.exec(apiKey);
1279
- return match ? match[1] ?? "" : "";
1280
- }
1281
-
1282
1339
  // src/auth-wire.ts
1283
1340
  function asWireAuthResult(raw) {
1284
1341
  if (typeof raw !== "object" || raw === null) return null;
@@ -2699,7 +2756,7 @@ var PalbeFlags = class {
2699
2756
  constructor(rt) {
2700
2757
  this.transport = new FlagsClient(rt.http);
2701
2758
  const browser = typeof document !== "undefined";
2702
- const ref = rt.config.environmentRef;
2759
+ const ref = rt.projectRef;
2703
2760
  const options = {
2704
2761
  auth: palbeAuthAdapter(rt.auth),
2705
2762
  ...ref ? { storageKey: `palbe.flags.${ref}` } : {},
@@ -9098,15 +9155,13 @@ function defaultSessionStorage(key) {
9098
9155
  }
9099
9156
 
9100
9157
  // src/version.ts
9101
- var VERSION = "7.2.2";
9158
+ var VERSION = "7.3.1";
9102
9159
 
9103
9160
  // src/runtime.ts
9104
9161
  function buildRuntime(config) {
9105
- const keyEnvironmentRef = environmentRefFromPublishableApiKey(config.apiKey);
9106
- if (keyEnvironmentRef === "") {
9107
- throw new Error("PalbeConfig.apiKey does not contain a valid publishable Environment identity");
9108
- } else if (config.environmentRef !== keyEnvironmentRef) {
9109
- throw new Error("PalbeConfig.environmentRef must match the Environment identity in apiKey");
9162
+ const projectRef = environmentRefFromPublishableApiKey(config.apiKey);
9163
+ if (projectRef === "") {
9164
+ throw new Error("PalbeConfig.apiKey does not contain a valid publishable project identity");
9110
9165
  }
9111
9166
  let runtimeURL;
9112
9167
  try {
@@ -9114,8 +9169,8 @@ function buildRuntime(config) {
9114
9169
  } catch {
9115
9170
  throw new Error("PalbeConfig.url must be a valid URL");
9116
9171
  }
9117
- if (runtimeURL.hostname.endsWith(".palbase.studio") && runtimeURL.hostname.split(".")[0] !== config.environmentRef) {
9118
- throw new Error("PalbeConfig.url must match environmentRef for palbase.studio");
9172
+ if (runtimeURL.hostname.endsWith(".palbase.studio") && runtimeURL.hostname.split(".")[0] !== projectRef) {
9173
+ throw new Error("PalbeConfig.url must match the project identity in apiKey for palbase.studio");
9119
9174
  }
9120
9175
  const http = new HttpClient(config.apiKey, {
9121
9176
  url: config.url,
@@ -9125,7 +9180,7 @@ function buildRuntime(config) {
9125
9180
  const tokenManager = new TokenManager();
9126
9181
  http.tokenManager = tokenManager;
9127
9182
  const authClient = new AuthClient(http, tokenManager);
9128
- const ref = config.environmentRef;
9183
+ const ref = projectRef;
9129
9184
  const storage = config.storage ?? defaultSessionStorage(ref ? `palbe.session.${ref}` : void 0);
9130
9185
  const persisted = storage.load();
9131
9186
  if (persisted) {
@@ -9170,6 +9225,7 @@ function buildRuntime(config) {
9170
9225
  let perf;
9171
9226
  const rt = {
9172
9227
  config,
9228
+ projectRef,
9173
9229
  http,
9174
9230
  tokenManager,
9175
9231
  authClient,
@@ -9412,7 +9468,7 @@ function setupPalbeNext() {
9412
9468
  const config = getRuntime().config;
9413
9469
  __configure({
9414
9470
  ...config,
9415
- storage: cookieSessionStorage(config.environmentRef)
9471
+ storage: cookieSessionStorage(environmentRefFromPublishableApiKey(config.apiKey))
9416
9472
  });
9417
9473
  }
9418
9474
  // Annotate the CommonJS export names for ESM import in node: