@palbase/web 7.3.4 → 7.3.6

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/internal.js CHANGED
@@ -6,8 +6,8 @@ import {
6
6
  createBoundClient,
7
7
  getRuntime,
8
8
  onConfigured
9
- } from "./chunk-PYJ3CMA2.js";
10
- import "./chunk-RAP37ILS.js";
9
+ } from "./chunk-SQWG3PTU.js";
10
+ import "./chunk-6DGCUHSO.js";
11
11
  import "./chunk-CFDU23TB.js";
12
12
  import "./chunk-PZ5AY32C.js";
13
13
  export {
@@ -70,6 +70,28 @@ function asPowChallenge(details) {
70
70
  return { id, prefix, difficulty };
71
71
  }
72
72
  var encoder = new TextEncoder();
73
+ var hasher = null;
74
+ async function digester() {
75
+ if (hasher) return hasher;
76
+ const runtime = globalThis;
77
+ const nodeish = runtime.process?.versions?.node !== void 0 || runtime.process?.versions?.bun !== void 0;
78
+ if (nodeish) {
79
+ try {
80
+ const mod = await import(
81
+ /* @vite-ignore */
82
+ `${"node:"}crypto`
83
+ );
84
+ if (typeof mod.createHash === "function") {
85
+ const createHash = mod.createHash;
86
+ hasher = (input) => new Uint8Array(createHash("sha256").update(input).digest());
87
+ return hasher;
88
+ }
89
+ } catch {
90
+ }
91
+ }
92
+ hasher = async (input) => new Uint8Array(await crypto.subtle.digest("SHA-256", encoder.encode(input)));
93
+ return hasher;
94
+ }
73
95
  var now = () => typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
74
96
  function leadingZeroBits(hash) {
75
97
  let bits = 0;
@@ -86,14 +108,19 @@ var MAX_POW_DIFFICULTY = 24;
86
108
  function powBudget(difficulty) {
87
109
  return 8 * 2 ** difficulty;
88
110
  }
89
- var POW_DEADLINE_MS = 12e4;
111
+ var POW_TIME_BUDGET_MS = 12e4;
112
+ var CALIBRATION_WARMUP = 1024;
113
+ var CALIBRATION_END = 9216;
90
114
  async function solvePowChallenge(challenge, maxIterations = powBudget(challenge.difficulty), signal) {
91
115
  if (challenge.difficulty > MAX_POW_DIFFICULTY) {
92
116
  throw new Error(
93
117
  `proof-of-work: refusing difficulty ${challenge.difficulty}; this client attempts at most ${MAX_POW_DIFFICULTY}, which is the highest a Palbase stack issues`
94
118
  );
95
119
  }
96
- const deadline = now() + POW_DEADLINE_MS;
120
+ const digest = await digester();
121
+ let warmedAt = 0;
122
+ let calibrated = false;
123
+ let deadline = Number.POSITIVE_INFINITY;
97
124
  for (let nonce = 0; nonce < maxIterations; nonce++) {
98
125
  if ((nonce & 1023) === 0) {
99
126
  if (signal?.aborted) {
@@ -101,12 +128,27 @@ async function solvePowChallenge(challenge, maxIterations = powBudget(challenge.
101
128
  }
102
129
  if (now() > deadline) {
103
130
  throw new Error(
104
- `proof-of-work: gave up after ${POW_DEADLINE_MS / 1e3}s at difficulty ${challenge.difficulty} (${nonce} attempts)`
131
+ `proof-of-work: gave up on difficulty ${challenge.difficulty} after ${POW_TIME_BUDGET_MS / 1e3}s and ${nonce.toLocaleString()} attempts \u2014 the tail this run drew is longer than the allowance`
105
132
  );
106
133
  }
107
134
  }
108
- const digest = await crypto.subtle.digest("SHA-256", encoder.encode(challenge.prefix + nonce));
109
- if (leadingZeroBits(new Uint8Array(digest)) >= challenge.difficulty) {
135
+ if (nonce === CALIBRATION_WARMUP) {
136
+ warmedAt = now();
137
+ }
138
+ if (!calibrated && nonce === CALIBRATION_END) {
139
+ calibrated = true;
140
+ const elapsed = Math.max(now() - warmedAt, 1e-3);
141
+ const rate = (CALIBRATION_END - CALIBRATION_WARMUP) / (elapsed / 1e3);
142
+ const expectedMs = 2 ** challenge.difficulty / rate * 1e3;
143
+ if (expectedMs > POW_TIME_BUDGET_MS) {
144
+ throw new Error(
145
+ `proof-of-work: difficulty ${challenge.difficulty} needs about ${Math.round(expectedMs / 1e3)}s here (${Math.round(rate).toLocaleString()} digests/s) and this client allows ${POW_TIME_BUDGET_MS / 1e3}s; refusing before spending the time rather than after`
146
+ );
147
+ }
148
+ deadline = now() + (POW_TIME_BUDGET_MS - (now() - warmedAt));
149
+ }
150
+ const hash = await digest(challenge.prefix + nonce);
151
+ if (leadingZeroBits(hash) >= challenge.difficulty) {
110
152
  return {
111
153
  [POW_CHALLENGE_ID_HEADER]: challenge.id,
112
154
  [POW_NONCE_HEADER]: String(nonce)
@@ -9177,7 +9219,7 @@ function defaultSessionStorage(key) {
9177
9219
  }
9178
9220
 
9179
9221
  // src/version.ts
9180
- var VERSION = "7.3.4";
9222
+ var VERSION = "7.3.6";
9181
9223
 
9182
9224
  // src/runtime.ts
9183
9225
  function buildRuntime(config) {
@@ -9185,15 +9227,11 @@ function buildRuntime(config) {
9185
9227
  if (projectRef === "") {
9186
9228
  throw new Error("PalbeConfig.apiKey does not contain a valid publishable project identity");
9187
9229
  }
9188
- let runtimeURL;
9189
9230
  try {
9190
- runtimeURL = new URL(config.url);
9231
+ new URL(config.url);
9191
9232
  } catch {
9192
9233
  throw new Error("PalbeConfig.url must be a valid URL");
9193
9234
  }
9194
- if (runtimeURL.hostname.endsWith(".palbase.studio") && runtimeURL.hostname.split(".")[0] !== projectRef) {
9195
- throw new Error("PalbeConfig.url must match the project identity in apiKey for palbase.studio");
9196
- }
9197
9235
  const http = new HttpClient(config.apiKey, {
9198
9236
  url: config.url,
9199
9237
  headers: { "X-Client-Info": `palbe-web/${VERSION}`, ...config.headers }