@palbase/web 7.2.2 → 7.3.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.
Files changed (38) 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-IREKQSHT.js → chunk-YBURINUN.js} +60 -14
  4. package/dist/chunk-YBURINUN.js.map +1 -0
  5. package/dist/gen/cli.cjs +6 -12
  6. package/dist/gen/cli.cjs.map +1 -1
  7. package/dist/gen/cli.js +6 -12
  8. package/dist/gen/cli.js.map +1 -1
  9. package/dist/index.cjs +51 -4
  10. package/dist/index.cjs.map +1 -1
  11. package/dist/index.d.cts +3 -3
  12. package/dist/index.d.ts +3 -3
  13. package/dist/index.js +1 -1
  14. package/dist/internal.cjs +59 -13
  15. package/dist/internal.cjs.map +1 -1
  16. package/dist/internal.d.cts +3 -3
  17. package/dist/internal.d.ts +3 -3
  18. package/dist/internal.js +1 -1
  19. package/dist/next/client.cjs +67 -21
  20. package/dist/next/client.cjs.map +1 -1
  21. package/dist/next/client.js +5 -3
  22. package/dist/next/client.js.map +1 -1
  23. package/dist/next/index.cjs +73 -27
  24. package/dist/next/index.cjs.map +1 -1
  25. package/dist/next/index.d.cts +2 -22
  26. package/dist/next/index.d.ts +2 -22
  27. package/dist/next/index.js +5 -4
  28. package/dist/next/index.js.map +1 -1
  29. package/dist/{pb-DdzpEkPY.d.ts → pb-BRlmBIAm.d.ts} +1 -1
  30. package/dist/{pb-CfYQGEn0.d.cts → pb-WAQvwCfM.d.cts} +1 -1
  31. package/dist/react/index.cjs +50 -3
  32. package/dist/react/index.cjs.map +1 -1
  33. package/dist/react/index.d.cts +1 -1
  34. package/dist/react/index.d.ts +1 -1
  35. package/dist/react/index.js +1 -1
  36. package/package.json +13 -13
  37. package/LICENSE +0 -21
  38. package/dist/chunk-IREKQSHT.js.map +0 -1
@@ -653,10 +653,8 @@ interface PalbeOAuthConfig {
653
653
  interface PalbeConfig {
654
654
  url: string;
655
655
  apiKey: string;
656
- /** Registered app identity persisted by `palbase web link`. */
656
+ /** Registered app identity persisted by `palbase link`. */
657
657
  appId: string;
658
- /** Stable reference of the linked Palbase Environment. */
659
- environmentRef: string;
660
658
  oauth?: PalbeOAuthConfig;
661
659
  /**
662
660
  * Refresh-token persistence. Default: environment-scoped localStorage in
@@ -1640,6 +1638,13 @@ declare class PalbeRealtime {
1640
1638
 
1641
1639
  interface PalbeRuntime {
1642
1640
  config: PalbeConfig;
1641
+ /**
1642
+ * The project this runtime talks to, read from the publishable key.
1643
+ *
1644
+ * Exposed here so every consumer takes it from ONE derivation. It used to be
1645
+ * a field on the config that had to equal the key's — see buildRuntime.
1646
+ */
1647
+ projectRef: string;
1643
1648
  http: HttpClient$1;
1644
1649
  tokenManager: TokenManager$1;
1645
1650
  authClient: AuthClient;
@@ -653,10 +653,8 @@ interface PalbeOAuthConfig {
653
653
  interface PalbeConfig {
654
654
  url: string;
655
655
  apiKey: string;
656
- /** Registered app identity persisted by `palbase web link`. */
656
+ /** Registered app identity persisted by `palbase link`. */
657
657
  appId: string;
658
- /** Stable reference of the linked Palbase Environment. */
659
- environmentRef: string;
660
658
  oauth?: PalbeOAuthConfig;
661
659
  /**
662
660
  * Refresh-token persistence. Default: environment-scoped localStorage in
@@ -1640,6 +1638,13 @@ declare class PalbeRealtime {
1640
1638
 
1641
1639
  interface PalbeRuntime {
1642
1640
  config: PalbeConfig;
1641
+ /**
1642
+ * The project this runtime talks to, read from the publishable key.
1643
+ *
1644
+ * Exposed here so every consumer takes it from ONE derivation. It used to be
1645
+ * a field on the config that had to equal the key's — see buildRuntime.
1646
+ */
1647
+ projectRef: string;
1643
1648
  http: HttpClient$1;
1644
1649
  tokenManager: TokenManager$1;
1645
1650
  authClient: AuthClient;
@@ -33,6 +33,47 @@ function redactUrl(rawUrl) {
33
33
  return path.split("/").map((seg2) => isSensitiveSegment(seg2) ? ":id" : seg2).join("/");
34
34
  }
35
35
 
36
+ // src/pow.ts
37
+ var POW_CHALLENGE_ID_HEADER = "X-PoW-Challenge-ID";
38
+ var POW_NONCE_HEADER = "X-PoW-Nonce";
39
+ function asPowChallenge(details) {
40
+ if (typeof details !== "object" || details === null) return null;
41
+ const env = details;
42
+ if (env.error !== "pow_required") return null;
43
+ const c = env.challenge;
44
+ if (typeof c !== "object" || c === null) return null;
45
+ const { id, prefix, difficulty } = c;
46
+ if (typeof id !== "string" || typeof prefix !== "string") return null;
47
+ if (typeof difficulty !== "number" || !Number.isInteger(difficulty) || difficulty < 0) return null;
48
+ return { id, prefix, difficulty };
49
+ }
50
+ var encoder = new TextEncoder();
51
+ function leadingZeroBits(hash) {
52
+ let bits = 0;
53
+ for (const byte of hash) {
54
+ if (byte === 0) {
55
+ bits += 8;
56
+ continue;
57
+ }
58
+ return bits + Math.clz32(byte) - 24;
59
+ }
60
+ return bits;
61
+ }
62
+ async function solvePowChallenge(challenge, maxIterations = 1 << 24) {
63
+ for (let nonce = 0; nonce < maxIterations; nonce++) {
64
+ const digest = await crypto.subtle.digest("SHA-256", encoder.encode(challenge.prefix + nonce));
65
+ if (leadingZeroBits(new Uint8Array(digest)) >= challenge.difficulty) {
66
+ return {
67
+ [POW_CHALLENGE_ID_HEADER]: challenge.id,
68
+ [POW_NONCE_HEADER]: String(nonce)
69
+ };
70
+ }
71
+ }
72
+ throw new Error(
73
+ `proof-of-work: no nonce found for difficulty ${challenge.difficulty} within ${maxIterations} attempts`
74
+ );
75
+ }
76
+
36
77
  // src/request.ts
37
78
  var MUTATING = /* @__PURE__ */ new Set(["POST", "PUT", "PATCH", "DELETE"]);
38
79
  var PERF_EXCLUDED_PREFIX = "/v1/analytics/";
@@ -56,11 +97,11 @@ async function palbeRequest(rt, method, path, spec = {}) {
56
97
  if (MUTATING.has(method) && !callerHasKey) {
57
98
  headers["Idempotency-Key"] = crypto.randomUUID();
58
99
  }
59
- const attempt = async () => {
100
+ const attempt = async (extra) => {
60
101
  try {
61
102
  return await rt.http.request(method, path, {
62
103
  body: spec.body,
63
- headers,
104
+ headers: extra ? { ...headers, ...extra } : headers,
64
105
  signal: spec.signal
65
106
  });
66
107
  } catch (e) {
@@ -95,6 +136,12 @@ async function palbeRequest(rt, method, path, spec = {}) {
95
136
  }
96
137
  res = await attempt();
97
138
  }
139
+ if (res.error?.status === 403 && res.error.code === "pow_required") {
140
+ const challenge = asPowChallenge(res.error.details);
141
+ if (challenge) {
142
+ res = await attempt(await solvePowChallenge(challenge));
143
+ }
144
+ }
98
145
  } catch (e) {
99
146
  if (!isAbort(e)) record(asPalbaseError(e)?.status ?? 0);
100
147
  throw e;
@@ -835,7 +882,7 @@ var AnalyticsState = class {
835
882
  idKey;
836
883
  optOutKey;
837
884
  constructor(rt) {
838
- const ref = rt.config.environmentRef;
885
+ const ref = rt.projectRef;
839
886
  this.idKey = ref ? `palbe.analytics.id.${ref}` : "palbe.analytics.id";
840
887
  this.optOutKey = ref ? `palbe.analytics.optout.${ref}` : "palbe.analytics.optout";
841
888
  rt.auth.onAuthEvent((event) => {
@@ -2474,7 +2521,7 @@ var PalbeFlags = class {
2474
2521
  constructor(rt) {
2475
2522
  this.transport = new FlagsClient(rt.http);
2476
2523
  const browser = typeof document !== "undefined";
2477
- const ref = rt.config.environmentRef;
2524
+ const ref = rt.projectRef;
2478
2525
  const options = {
2479
2526
  auth: palbeAuthAdapter(rt.auth),
2480
2527
  ...ref ? { storageKey: `palbe.flags.${ref}` } : {},
@@ -8873,15 +8920,13 @@ function defaultSessionStorage(key) {
8873
8920
  }
8874
8921
 
8875
8922
  // src/version.ts
8876
- var VERSION = "7.2.2";
8923
+ var VERSION = "7.3.0";
8877
8924
 
8878
8925
  // src/runtime.ts
8879
8926
  function buildRuntime(config) {
8880
- const keyEnvironmentRef = environmentRefFromPublishableApiKey(config.apiKey);
8881
- if (keyEnvironmentRef === "") {
8882
- throw new Error("PalbeConfig.apiKey does not contain a valid publishable Environment identity");
8883
- } else if (config.environmentRef !== keyEnvironmentRef) {
8884
- throw new Error("PalbeConfig.environmentRef must match the Environment identity in apiKey");
8927
+ const projectRef = environmentRefFromPublishableApiKey(config.apiKey);
8928
+ if (projectRef === "") {
8929
+ throw new Error("PalbeConfig.apiKey does not contain a valid publishable project identity");
8885
8930
  }
8886
8931
  let runtimeURL;
8887
8932
  try {
@@ -8889,8 +8934,8 @@ function buildRuntime(config) {
8889
8934
  } catch {
8890
8935
  throw new Error("PalbeConfig.url must be a valid URL");
8891
8936
  }
8892
- if (runtimeURL.hostname.endsWith(".palbase.studio") && runtimeURL.hostname.split(".")[0] !== config.environmentRef) {
8893
- throw new Error("PalbeConfig.url must match environmentRef for palbase.studio");
8937
+ if (runtimeURL.hostname.endsWith(".palbase.studio") && runtimeURL.hostname.split(".")[0] !== projectRef) {
8938
+ throw new Error("PalbeConfig.url must match the project identity in apiKey for palbase.studio");
8894
8939
  }
8895
8940
  const http = new HttpClient(config.apiKey, {
8896
8941
  url: config.url,
@@ -8900,7 +8945,7 @@ function buildRuntime(config) {
8900
8945
  const tokenManager = new TokenManager();
8901
8946
  http.tokenManager = tokenManager;
8902
8947
  const authClient = new AuthClient(http, tokenManager);
8903
- const ref = config.environmentRef;
8948
+ const ref = projectRef;
8904
8949
  const storage = config.storage ?? defaultSessionStorage(ref ? `palbe.session.${ref}` : void 0);
8905
8950
  const persisted = storage.load();
8906
8951
  if (persisted) {
@@ -8945,6 +8990,7 @@ function buildRuntime(config) {
8945
8990
  let perf;
8946
8991
  const rt = {
8947
8992
  config,
8993
+ projectRef,
8948
8994
  http,
8949
8995
  tokenManager,
8950
8996
  authClient,
@@ -9298,4 +9344,4 @@ export {
9298
9344
  pb,
9299
9345
  createBoundClient
9300
9346
  };
9301
- //# sourceMappingURL=chunk-IREKQSHT.js.map
9347
+ //# sourceMappingURL=chunk-YBURINUN.js.map