@aithos/sdk 0.1.0-alpha.13 → 0.1.0-alpha.14

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.
@@ -205,6 +205,15 @@ export declare class AithosAuth {
205
205
  importMandate(input: ImportMandateInput): Promise<DelegateInfo>;
206
206
  removeMandate(mandateId: string): Promise<void>;
207
207
  signInWithGoogle(opts?: SignInWithGoogleOptions): never;
208
+ /**
209
+ * Public entrypoint — dedupes concurrent calls (React StrictMode).
210
+ * The first call kicks off the actual exchange; subsequent calls
211
+ * before that promise resolves return the SAME promise so they all
212
+ * receive the same `AithosSession | null`. Otherwise StrictMode's
213
+ * second invocation would race against the URL clean done by the
214
+ * first call and resolve to `null`, robbing the AuthCallback page
215
+ * of the session it actually obtained.
216
+ */
208
217
  handleCallback(): Promise<AithosSession | null>;
209
218
  exchange(aithosCode: string): Promise<AithosSession>;
210
219
  /**
package/dist/src/auth.js CHANGED
@@ -47,6 +47,16 @@ export class AithosAuth {
47
47
  #ownerSigners = null;
48
48
  /** Active delegate registry. */
49
49
  #delegates = new DelegateRegistry();
50
+ /**
51
+ * In-flight (or just-resolved) `handleCallback()` result. React
52
+ * StrictMode (dev) double-invokes the mount effect — the URL clean
53
+ * inside the first call makes the second invocation see a clean URL
54
+ * and resolve to `null`, with the session it just consumed locked
55
+ * inside the first promise. Caching the result here lets both
56
+ * invocations resolve to the same value. Cleared on next mount via
57
+ * the wrapper's once-per-instance dedup.
58
+ */
59
+ #handleCallbackPromise = null;
50
60
  constructor(config = {}) {
51
61
  this.authBaseUrl = trimSlash(config.authBaseUrl ?? DEFAULT_AUTH_BASE_URL);
52
62
  this.apiBaseUrl = trimSlash(config.apiBaseUrl ?? DEFAULT_API_BASE_URL);
@@ -466,7 +476,41 @@ export class AithosAuth {
466
476
  this.#win.location.assign(url.toString());
467
477
  throw new AithosSDKError("auth_redirecting", "redirecting to google");
468
478
  }
479
+ /**
480
+ * Public entrypoint — dedupes concurrent calls (React StrictMode).
481
+ * The first call kicks off the actual exchange; subsequent calls
482
+ * before that promise resolves return the SAME promise so they all
483
+ * receive the same `AithosSession | null`. Otherwise StrictMode's
484
+ * second invocation would race against the URL clean done by the
485
+ * first call and resolve to `null`, robbing the AuthCallback page
486
+ * of the session it actually obtained.
487
+ */
469
488
  async handleCallback() {
489
+ if (!this.#win)
490
+ return null;
491
+ if (this.#handleCallbackPromise)
492
+ return this.#handleCallbackPromise;
493
+ const p = this.#doHandleCallback();
494
+ this.#handleCallbackPromise = p;
495
+ // Clear the cache once the promise settles so a subsequent
496
+ // signInWithGoogle round-trip on the same AithosAuth instance can
497
+ // process its own callback. We use `then(cleanup, cleanup)`
498
+ // rather than `finally(...)` because `finally` re-throws — without
499
+ // a downstream `.catch` the resulting promise becomes an
500
+ // unhandledrejection when `p` itself rejects (the caller already
501
+ // surfaces that rejection via the returned `p`). `then(success,
502
+ // error)` converts a rejection into a clean resolution on this
503
+ // side-effect chain so node:test doesn't flag the orphan as a
504
+ // failure.
505
+ const clear = () => {
506
+ if (this.#handleCallbackPromise === p) {
507
+ this.#handleCallbackPromise = null;
508
+ }
509
+ };
510
+ p.then(clear, clear);
511
+ return p;
512
+ }
513
+ async #doHandleCallback() {
470
514
  if (!this.#win)
471
515
  return null;
472
516
  const here = new URL(this.#win.location.href);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aithos/sdk",
3
- "version": "0.1.0-alpha.13",
3
+ "version": "0.1.0-alpha.14",
4
4
  "description": "Aithos SDK — high-level TypeScript developer kit for building agentic apps on the Aithos protocol. Wraps @aithos/protocol-client and exposes the Aithos compute proxy and wallet (Stripe top-up) endpoints.",
5
5
  "keywords": [
6
6
  "aithos",