@palbase/web 7.3.0 → 7.3.2

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.
@@ -6,8 +6,8 @@ import {
6
6
  import {
7
7
  __configure,
8
8
  getRuntime
9
- } from "../chunk-YBURINUN.js";
10
- import "../chunk-ACCJV6FV.js";
9
+ } from "../chunk-TQAQR3OP.js";
10
+ import "../chunk-HKZVA3I3.js";
11
11
  import {
12
12
  environmentRefFromPublishableApiKey
13
13
  } from "../chunk-CFDU23TB.js";
@@ -166,6 +166,54 @@ var PalbaseError = class extends Error {
166
166
  this.details = details;
167
167
  }
168
168
  };
169
+ var POW_CHALLENGE_ID_HEADER = "X-PoW-Challenge-ID";
170
+ var POW_NONCE_HEADER = "X-PoW-Nonce";
171
+ function asPowChallenge(details) {
172
+ if (typeof details !== "object" || details === null) return null;
173
+ const env = details;
174
+ if (env.error !== "pow_required") return null;
175
+ const c = env.challenge;
176
+ if (typeof c !== "object" || c === null) return null;
177
+ const { id, prefix, difficulty } = c;
178
+ if (typeof id !== "string" || typeof prefix !== "string") return null;
179
+ if (typeof difficulty !== "number" || !Number.isInteger(difficulty) || difficulty < 0) return null;
180
+ return { id, prefix, difficulty };
181
+ }
182
+ var encoder = new TextEncoder();
183
+ function leadingZeroBits(hash) {
184
+ let bits = 0;
185
+ for (const byte of hash) {
186
+ if (byte === 0) {
187
+ bits += 8;
188
+ continue;
189
+ }
190
+ return bits + Math.clz32(byte) - 24;
191
+ }
192
+ return bits;
193
+ }
194
+ var MAX_POW_DIFFICULTY = 24;
195
+ function powBudget(difficulty) {
196
+ return 8 * 2 ** difficulty;
197
+ }
198
+ async function solvePowChallenge(challenge, maxIterations = powBudget(challenge.difficulty)) {
199
+ if (challenge.difficulty > MAX_POW_DIFFICULTY) {
200
+ throw new Error(
201
+ `proof-of-work: refusing difficulty ${challenge.difficulty}; this client attempts at most ${MAX_POW_DIFFICULTY}, which is the highest a Palbase stack issues`
202
+ );
203
+ }
204
+ for (let nonce = 0; nonce < maxIterations; nonce++) {
205
+ const digest = await crypto.subtle.digest("SHA-256", encoder.encode(challenge.prefix + nonce));
206
+ if (leadingZeroBits(new Uint8Array(digest)) >= challenge.difficulty) {
207
+ return {
208
+ [POW_CHALLENGE_ID_HEADER]: challenge.id,
209
+ [POW_NONCE_HEADER]: String(nonce)
210
+ };
211
+ }
212
+ }
213
+ throw new Error(
214
+ `proof-of-work: no nonce found for difficulty ${challenge.difficulty} within ${maxIterations} attempts`
215
+ );
216
+ }
169
217
  function detectPlatform() {
170
218
  if (typeof Deno !== "undefined") {
171
219
  return "deno";
@@ -302,9 +350,9 @@ var HttpClient = class _HttpClient {
302
350
  }
303
351
  return headers;
304
352
  }
305
- async executeWithRetry(method, path, options, attempt) {
353
+ async executeWithRetry(method, path, options, attempt, earned) {
306
354
  const url = `${this.getBaseUrl()}${path}`;
307
- const headers = this.buildHeaders(options);
355
+ const headers = { ...this.buildHeaders(options), ...earned };
308
356
  for (const interceptor of this.interceptors) {
309
357
  await interceptor({ headers, method, path });
310
358
  }
@@ -323,7 +371,7 @@ var HttpClient = class _HttpClient {
323
371
  if (attempt < MAX_RETRIES - 1) {
324
372
  const backoff = INITIAL_BACKOFF_MS * 2 ** attempt;
325
373
  await this.delay(backoff);
326
- return this.executeWithRetry(method, path, options, attempt + 1);
374
+ return this.executeWithRetry(method, path, options, attempt + 1, earned);
327
375
  }
328
376
  throw new PalbaseError(
329
377
  "network_error",
@@ -337,7 +385,7 @@ var HttpClient = class _HttpClient {
337
385
  const parsed = retryAfter ? Number.parseInt(retryAfter, 10) : Number.NaN;
338
386
  const delayMs = Number.isNaN(parsed) ? INITIAL_BACKOFF_MS * 2 ** attempt : Math.min(parsed * 1e3, MAX_RETRY_DELAY_MS);
339
387
  await this.delay(delayMs);
340
- return this.executeWithRetry(method, path, options, attempt + 1);
388
+ return this.executeWithRetry(method, path, options, attempt + 1, earned);
341
389
  }
342
390
  }
343
391
  let data = null;
@@ -351,6 +399,18 @@ var HttpClient = class _HttpClient {
351
399
  errorBody = body;
352
400
  }
353
401
  }
402
+ if (response.status === 403 && !earned) {
403
+ const challenge = asPowChallenge(errorBody);
404
+ if (challenge) {
405
+ return this.executeWithRetry(
406
+ method,
407
+ path,
408
+ options,
409
+ attempt,
410
+ await solvePowChallenge(challenge)
411
+ );
412
+ }
413
+ }
354
414
  if (!response.ok) {
355
415
  return {
356
416
  data: null,
@@ -568,47 +628,6 @@ function redactUrl(rawUrl) {
568
628
  return path.split("/").map((seg2) => isSensitiveSegment(seg2) ? ":id" : seg2).join("/");
569
629
  }
570
630
 
571
- // src/pow.ts
572
- var POW_CHALLENGE_ID_HEADER = "X-PoW-Challenge-ID";
573
- var POW_NONCE_HEADER = "X-PoW-Nonce";
574
- function asPowChallenge(details) {
575
- if (typeof details !== "object" || details === null) return null;
576
- const env = details;
577
- if (env.error !== "pow_required") return null;
578
- const c = env.challenge;
579
- if (typeof c !== "object" || c === null) return null;
580
- const { id, prefix, difficulty } = c;
581
- if (typeof id !== "string" || typeof prefix !== "string") return null;
582
- if (typeof difficulty !== "number" || !Number.isInteger(difficulty) || difficulty < 0) return null;
583
- return { id, prefix, difficulty };
584
- }
585
- var encoder = new TextEncoder();
586
- function leadingZeroBits(hash) {
587
- let bits = 0;
588
- for (const byte of hash) {
589
- if (byte === 0) {
590
- bits += 8;
591
- continue;
592
- }
593
- return bits + Math.clz32(byte) - 24;
594
- }
595
- return bits;
596
- }
597
- async function solvePowChallenge(challenge, maxIterations = 1 << 24) {
598
- for (let nonce = 0; nonce < maxIterations; nonce++) {
599
- const digest = await crypto.subtle.digest("SHA-256", encoder.encode(challenge.prefix + nonce));
600
- if (leadingZeroBits(new Uint8Array(digest)) >= challenge.difficulty) {
601
- return {
602
- [POW_CHALLENGE_ID_HEADER]: challenge.id,
603
- [POW_NONCE_HEADER]: String(nonce)
604
- };
605
- }
606
- }
607
- throw new Error(
608
- `proof-of-work: no nonce found for difficulty ${challenge.difficulty} within ${maxIterations} attempts`
609
- );
610
- }
611
-
612
631
  // src/request.ts
613
632
  var MUTATING = /* @__PURE__ */ new Set(["POST", "PUT", "PATCH", "DELETE"]);
614
633
  var PERF_EXCLUDED_PREFIX = "/v1/analytics/";
@@ -9354,7 +9373,7 @@ function defaultSessionStorage(key) {
9354
9373
  }
9355
9374
 
9356
9375
  // src/version.ts
9357
- var VERSION = "7.3.0";
9376
+ var VERSION = "7.3.2";
9358
9377
 
9359
9378
  // src/runtime.ts
9360
9379
  function buildRuntime(config) {