@palbase/web 4.0.0 → 4.0.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.
Files changed (48) hide show
  1. package/dist/_mls-wasm.cjs +32 -0
  2. package/dist/_mls-wasm.cjs.map +1 -0
  3. package/dist/_mls-wasm.js +11 -0
  4. package/dist/_mls-wasm.js.map +1 -0
  5. package/dist/{analytics-facade-DwOtlXPP.d.cts → analytics-facade-CaluA4bW.d.cts} +26 -1
  6. package/dist/{analytics-facade-Nk6J9Ncm.d.ts → analytics-facade-Cp3d4QI-.d.ts} +26 -1
  7. package/dist/{chunk-S7NAY3MW.js → chunk-CFDU23TB.js} +3 -10
  8. package/dist/chunk-CFDU23TB.js.map +1 -0
  9. package/dist/chunk-PZ5AY32C.js +10 -0
  10. package/dist/chunk-PZ5AY32C.js.map +1 -0
  11. package/dist/{chunk-NP4NIY7A.js → chunk-TW6YN354.js} +84 -27
  12. package/dist/chunk-TW6YN354.js.map +1 -0
  13. package/dist/gen/cli.cjs +5 -5
  14. package/dist/gen/cli.cjs.map +1 -1
  15. package/dist/gen/cli.js +6 -5
  16. package/dist/gen/cli.js.map +1 -1
  17. package/dist/index.cjs +91 -27
  18. package/dist/index.cjs.map +1 -1
  19. package/dist/index.d.cts +3 -3
  20. package/dist/index.d.ts +3 -3
  21. package/dist/index.js +3 -2
  22. package/dist/internal.cjs +90 -26
  23. package/dist/internal.cjs.map +1 -1
  24. package/dist/internal.d.cts +3 -3
  25. package/dist/internal.d.ts +3 -3
  26. package/dist/internal.js +3 -2
  27. package/dist/next/client.cjs +90 -26
  28. package/dist/next/client.cjs.map +1 -1
  29. package/dist/next/client.js +3 -2
  30. package/dist/next/client.js.map +1 -1
  31. package/dist/next/index.cjs +81 -27
  32. package/dist/next/index.cjs.map +1 -1
  33. package/dist/next/index.d.cts +2 -2
  34. package/dist/next/index.d.ts +2 -2
  35. package/dist/next/index.js +3 -2
  36. package/dist/next/index.js.map +1 -1
  37. package/dist/{pb-FG_nV7NR.d.ts → pb-DUK5qy81.d.ts} +1 -1
  38. package/dist/{pb-C9v5dEO6.d.cts → pb-DvV6ftmf.d.cts} +1 -1
  39. package/dist/react/index.cjs +10 -2
  40. package/dist/react/index.cjs.map +1 -1
  41. package/dist/react/index.d.cts +1 -1
  42. package/dist/react/index.d.ts +1 -1
  43. package/dist/react/index.js +3 -2
  44. package/dist/react/index.js.map +1 -1
  45. package/package.json +10 -3
  46. package/dist/chunk-NP4NIY7A.js.map +0 -1
  47. package/dist/chunk-S7NAY3MW.js.map +0 -1
  48. package/dist/pkg/palbe_mls_bg.wasm +0 -0
package/dist/index.cjs CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,11 +17,19 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
 
20
30
  // src/index.ts
21
- var index_exports = {};
22
- __export(index_exports, {
31
+ var src_exports = {};
32
+ __export(src_exports, {
23
33
  BackendError: () => BackendError,
24
34
  PalbeAnalytics: () => PalbeAnalytics,
25
35
  PalbeAuth: () => PalbeAuth,
@@ -35,7 +45,7 @@ __export(index_exports, {
35
45
  memorySessionStorage: () => memorySessionStorage,
36
46
  pb: () => pb
37
47
  });
38
- module.exports = __toCommonJS(index_exports);
48
+ module.exports = __toCommonJS(src_exports);
39
49
 
40
50
  // ../core/dist/index.js
41
51
  var CACHE_TTL_MS = 5 * 60 * 1e3;
@@ -177,6 +187,11 @@ var PERF_EXCLUDED_PREFIX = "/v1/analytics/";
177
187
  function isSelfTraced(path) {
178
188
  return path.startsWith(PERF_EXCLUDED_PREFIX);
179
189
  }
190
+ function isSessionKilled(status, code) {
191
+ if (status === 401) return code === "session_revoked";
192
+ if (status === 403) return code === "subject_fenced" || code === "subject_erased";
193
+ return false;
194
+ }
180
195
  function nowMs() {
181
196
  return typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
182
197
  }
@@ -212,7 +227,7 @@ async function palbeRequest(rt, method, path, spec = {}) {
212
227
  let res;
213
228
  try {
214
229
  res = await attempt();
215
- if (res.error?.status === 401 && rt.tokenManager.getRefreshToken() && rt.tokenManager.refreshFunction) {
230
+ if (res.error?.status === 401 && res.error.code !== "session_revoked" && rt.tokenManager.getRefreshToken() && rt.tokenManager.refreshFunction) {
216
231
  try {
217
232
  await rt.tokenManager.refreshSession();
218
233
  } catch (refreshErr) {
@@ -232,6 +247,9 @@ async function palbeRequest(rt, method, path, spec = {}) {
232
247
  if (!isAbort(e)) record(asPalbaseError(e)?.status ?? 0);
233
248
  throw e;
234
249
  }
250
+ if (res.error && isSessionKilled(res.error.status, res.error.code)) {
251
+ rt.auth.reactiveTeardown();
252
+ }
235
253
  record(res.error?.status ?? 200);
236
254
  return unwrap(res);
237
255
  }
@@ -459,7 +477,8 @@ var PalbeAuth = class {
459
477
  if (!this.signedInState) return;
460
478
  this.signedInState = false;
461
479
  this.cachedUser = null;
462
- const reason = this.signingOut ? "userInitiated" : "sessionExpired";
480
+ const reason = this.nextSignOutReason ?? (this.signingOut ? "userInitiated" : "sessionExpired");
481
+ this.nextSignOutReason = null;
463
482
  this.emitState({ status: "signedOut" });
464
483
  this.emitEvent({ type: "signedOut", reason });
465
484
  } else if (event === "TOKEN_REFRESHED") {
@@ -472,6 +491,10 @@ var PalbeAuth = class {
472
491
  rt;
473
492
  cachedUser = null;
474
493
  signingOut = false;
494
+ // Explicit signedOut reason pinned for the NEXT session clear (deleteAccount /
495
+ // reactiveTeardown set it before clearSession; the SIGNED_OUT handler consumes
496
+ // it exactly once, then resets to null → normal signOut/expiry split resumes).
497
+ nextSignOutReason = null;
475
498
  signingIn = false;
476
499
  // suppresses AuthClient's TOKEN_REFRESHED during re-signIn
477
500
  signedInState = false;
@@ -519,6 +542,45 @@ var PalbeAuth = class {
519
542
  this.cachedUser = null;
520
543
  }
521
544
  }
545
+ /**
546
+ * Self-service account erasure ("right to be forgotten"). Calls palauth
547
+ * `DELETE /auth/user` (session-authed + fresh re-auth): password users pass
548
+ * `{ password }`; passwordless/OAuth users rely on a freshly stepped-up
549
+ * session. On 202 the erasure workflow is durably queued AND every session is
550
+ * already revoked server-side — so we tear down local state (mirroring
551
+ * `signOut()`'s clear, minus the pointless `/logout`) and emit
552
+ * `signedOut{reason:'accountDeleted'}`.
553
+ *
554
+ * On 401 `reauth_required` / 503 `not_configured` (or `erasure_unavailable`)
555
+ * the request throws BEFORE the teardown line, so the local session is left
556
+ * fully intact — the deletion did not happen and the user is still signed in.
557
+ */
558
+ async deleteAccount(params = {}) {
559
+ const res = await palbeRequest(this.rt, "DELETE", "/auth/user", {
560
+ body: params.password ? { password: params.password } : {}
561
+ });
562
+ this.nextSignOutReason = "accountDeleted";
563
+ this.rt.tokenManager.clearSession();
564
+ this.rt.storage.clear();
565
+ this.cachedUser = null;
566
+ return { erasureId: res.erasure_id };
567
+ }
568
+ /**
569
+ * @internal — invoked by the transport choke point (`request.ts`), not app code.
570
+ * Reactive teardown when the server reports the session is gone: a 403
571
+ * `subject_fenced`/`subject_erased` (subject being erased) or a 401
572
+ * `session_revoked`. Clears local state and emits
573
+ * `signedOut{reason:'sessionInvalid'}` exactly once (deduped by
574
+ * `signedInState`). An ordinary 403 authz denial does NOT reach here —
575
+ * `request.ts` matches only the exact session-kill codes.
576
+ */
577
+ reactiveTeardown() {
578
+ if (!this.signedInState) return;
579
+ this.nextSignOutReason = "sessionInvalid";
580
+ this.rt.tokenManager.clearSession();
581
+ this.rt.storage.clear();
582
+ this.cachedUser = null;
583
+ }
522
584
  async getUser() {
523
585
  const raw = await palbeRequest(this.rt, "GET", "/auth/user");
524
586
  return mapWireUser(raw);
@@ -5458,31 +5520,29 @@ function date_now() {
5458
5520
  }
5459
5521
 
5460
5522
  // src/messaging/wasm/loader.ts
5461
- var import_meta = {};
5462
5523
  var GLUE_MODULE = "./palbe_mls_bg.js";
5463
5524
  var SNIPPET_MODULE = "./snippets/mls-rs-core-f99cdecbb456b09c/inline0.js";
5464
5525
  var inflight = null;
5465
5526
  var ready = null;
5466
- async function loadWasmModule() {
5467
- const wasmUrl = new URL("./pkg/palbe_mls_bg.wasm", import_meta.url);
5468
- if (wasmUrl.protocol === "file:") {
5469
- const fsSpecifier = ["node", "fs/promises"].join(":");
5470
- const { readFile } = await import(
5471
- /* webpackIgnore: true */
5472
- fsSpecifier
5473
- );
5474
- const bytes = await readFile(wasmUrl);
5475
- return WebAssembly.compile(bytes);
5527
+ function decodeBase64(encoded) {
5528
+ if (typeof encoded !== "string" || encoded.length === 0 || typeof globalThis.atob !== "function") {
5529
+ throw new Error("palbe-mls WASM asset is invalid");
5476
5530
  }
5477
- const response = await fetch(wasmUrl);
5478
- if (typeof WebAssembly.compileStreaming === "function") {
5479
- try {
5480
- return await WebAssembly.compileStreaming(Promise.resolve(response));
5481
- } catch {
5482
- }
5531
+ let binary;
5532
+ try {
5533
+ binary = globalThis.atob(encoded);
5534
+ } catch {
5535
+ throw new Error("palbe-mls WASM asset is invalid");
5536
+ }
5537
+ const bytes = new Uint8Array(binary.length);
5538
+ for (let index = 0; index < binary.length; index += 1) {
5539
+ bytes[index] = binary.charCodeAt(index);
5483
5540
  }
5484
- const buffer = await response.arrayBuffer();
5485
- return WebAssembly.compile(buffer);
5541
+ return bytes.buffer;
5542
+ }
5543
+ async function loadWasmModule() {
5544
+ const asset = await import("#palbase-mls-wasm");
5545
+ return WebAssembly.compile(decodeBase64(asset.default));
5486
5546
  }
5487
5547
  function buildImports() {
5488
5548
  return {
@@ -5493,7 +5553,7 @@ function buildImports() {
5493
5553
  function initMls() {
5494
5554
  if (ready) return Promise.resolve(ready);
5495
5555
  if (inflight) return inflight;
5496
- inflight = (async () => {
5556
+ const attempt = (async () => {
5497
5557
  const module2 = await loadWasmModule();
5498
5558
  const instance = await WebAssembly.instantiate(module2, buildImports());
5499
5559
  const setWasm = __wbg_set_wasm;
@@ -5512,7 +5572,11 @@ function initMls() {
5512
5572
  ready = g;
5513
5573
  return g;
5514
5574
  })();
5515
- return inflight;
5575
+ inflight = attempt;
5576
+ void attempt.catch(() => {
5577
+ if (inflight === attempt) inflight = null;
5578
+ });
5579
+ return attempt;
5516
5580
  }
5517
5581
  function requireMls() {
5518
5582
  if (!ready) {
@@ -7621,7 +7685,7 @@ function localStorageSessionStorage(key = DEFAULT_KEY) {
7621
7685
  }
7622
7686
 
7623
7687
  // src/version.ts
7624
- var VERSION = "4.0.0";
7688
+ var VERSION = "4.0.2";
7625
7689
 
7626
7690
  // src/internal.ts
7627
7691
  function getRuntime() {