@superatomai/application-react 0.0.3 → 0.0.4

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/index.d.cts CHANGED
@@ -2561,12 +2561,18 @@ type SuperAtomAuthErrorCode =
2561
2561
  | 'network';
2562
2562
  declare class SuperAtomAuthError extends Error {
2563
2563
  readonly code: SuperAtomAuthErrorCode;
2564
+ /**
2565
+ * Why Superatom refused it, verbatim — `expired`, `bad_signature`,
2566
+ * `bad_access_filters`, `inactive`, … Present for `exchange_rejected` only.
2567
+ */
2568
+ readonly reason?: string;
2564
2569
  /** HTTP status from sa-api, when there was a response. */
2565
2570
  readonly status?: number;
2566
2571
  /** True when retrying cannot help — see the module comment. */
2567
2572
  readonly fatal: boolean;
2568
2573
  constructor(code: SuperAtomAuthErrorCode, message: string, options: {
2569
2574
  status?: number;
2575
+ reason?: string;
2570
2576
  fatal: boolean;
2571
2577
  cause?: unknown;
2572
2578
  });
@@ -2585,6 +2591,8 @@ interface SdkSessionOptions {
2585
2591
  * null once a sign-in succeeds.
2586
2592
  */
2587
2593
  onRetrying?: (error: SuperAtomAuthError | null) => void;
2594
+ /** True while an exchange is in flight, false when it finishes either way. */
2595
+ onSigningIn?: (signingIn: boolean) => void;
2588
2596
  /** sa-api base URL. Default: prod. */
2589
2597
  apiUrl?: string;
2590
2598
  debug?: boolean;
@@ -3865,6 +3873,12 @@ interface UseSuperAtomReturn {
3865
3873
  user: SdkUser | null;
3866
3874
  /** The sign-in failure that stopped the SDK, if any (same as passed to `onAuthError`). */
3867
3875
  authError: SuperAtomAuthError | null;
3876
+ /**
3877
+ * A sign-in attempt is in flight — at start, on renewal, and after
3878
+ * `reconnect()`. The chat already shows "Signing in…" by itself; use this only
3879
+ * if you want your own screen for it.
3880
+ */
3881
+ isSigningIn: boolean;
3868
3882
  /** Try signing in and connecting again — e.g. after the user signed in again on your side. */
3869
3883
  reconnect: () => void;
3870
3884
  }
@@ -3882,7 +3896,7 @@ interface ChatInputProps {
3882
3896
  isResponding?: boolean;
3883
3897
  onStop?: () => void;
3884
3898
  }
3885
- declare function ChatInput({ input, setInput, onSend, disabled, placeholder, primaryColor, className, isResponding, onStop, }: ChatInputProps): react_jsx_runtime.JSX.Element;
3899
+ declare function ChatInput({ input, setInput, onSend, disabled, placeholder, primaryColor, className, isResponding, onStop, }: ChatInputProps): react_jsx_runtime.JSX.Element | null;
3886
3900
 
3887
3901
  interface MessageListProps {
3888
3902
  messages: ChatMessage[];
@@ -3962,7 +3976,7 @@ interface SidebarProps {
3962
3976
  }>;
3963
3977
  primaryColor?: string;
3964
3978
  }
3965
- declare function Sidebar({ children, className, onItemClick, onNewChat, threads, activeThreadId, onSelectThread, onDeleteThread, onRenameThread, primaryColor, }: SidebarProps): react_jsx_runtime.JSX.Element;
3979
+ declare function Sidebar({ children, className, onItemClick, onNewChat, threads, activeThreadId, onSelectThread, onDeleteThread, onRenameThread, primaryColor, }: SidebarProps): react_jsx_runtime.JSX.Element | null;
3966
3980
 
3967
3981
  interface NewChatHeroProps {
3968
3982
  /** The chat input to center, e.g. <ChatInput ... /> */
package/dist/index.d.ts CHANGED
@@ -2561,12 +2561,18 @@ type SuperAtomAuthErrorCode =
2561
2561
  | 'network';
2562
2562
  declare class SuperAtomAuthError extends Error {
2563
2563
  readonly code: SuperAtomAuthErrorCode;
2564
+ /**
2565
+ * Why Superatom refused it, verbatim — `expired`, `bad_signature`,
2566
+ * `bad_access_filters`, `inactive`, … Present for `exchange_rejected` only.
2567
+ */
2568
+ readonly reason?: string;
2564
2569
  /** HTTP status from sa-api, when there was a response. */
2565
2570
  readonly status?: number;
2566
2571
  /** True when retrying cannot help — see the module comment. */
2567
2572
  readonly fatal: boolean;
2568
2573
  constructor(code: SuperAtomAuthErrorCode, message: string, options: {
2569
2574
  status?: number;
2575
+ reason?: string;
2570
2576
  fatal: boolean;
2571
2577
  cause?: unknown;
2572
2578
  });
@@ -2585,6 +2591,8 @@ interface SdkSessionOptions {
2585
2591
  * null once a sign-in succeeds.
2586
2592
  */
2587
2593
  onRetrying?: (error: SuperAtomAuthError | null) => void;
2594
+ /** True while an exchange is in flight, false when it finishes either way. */
2595
+ onSigningIn?: (signingIn: boolean) => void;
2588
2596
  /** sa-api base URL. Default: prod. */
2589
2597
  apiUrl?: string;
2590
2598
  debug?: boolean;
@@ -3865,6 +3873,12 @@ interface UseSuperAtomReturn {
3865
3873
  user: SdkUser | null;
3866
3874
  /** The sign-in failure that stopped the SDK, if any (same as passed to `onAuthError`). */
3867
3875
  authError: SuperAtomAuthError | null;
3876
+ /**
3877
+ * A sign-in attempt is in flight — at start, on renewal, and after
3878
+ * `reconnect()`. The chat already shows "Signing in…" by itself; use this only
3879
+ * if you want your own screen for it.
3880
+ */
3881
+ isSigningIn: boolean;
3868
3882
  /** Try signing in and connecting again — e.g. after the user signed in again on your side. */
3869
3883
  reconnect: () => void;
3870
3884
  }
@@ -3882,7 +3896,7 @@ interface ChatInputProps {
3882
3896
  isResponding?: boolean;
3883
3897
  onStop?: () => void;
3884
3898
  }
3885
- declare function ChatInput({ input, setInput, onSend, disabled, placeholder, primaryColor, className, isResponding, onStop, }: ChatInputProps): react_jsx_runtime.JSX.Element;
3899
+ declare function ChatInput({ input, setInput, onSend, disabled, placeholder, primaryColor, className, isResponding, onStop, }: ChatInputProps): react_jsx_runtime.JSX.Element | null;
3886
3900
 
3887
3901
  interface MessageListProps {
3888
3902
  messages: ChatMessage[];
@@ -3962,7 +3976,7 @@ interface SidebarProps {
3962
3976
  }>;
3963
3977
  primaryColor?: string;
3964
3978
  }
3965
- declare function Sidebar({ children, className, onItemClick, onNewChat, threads, activeThreadId, onSelectThread, onDeleteThread, onRenameThread, primaryColor, }: SidebarProps): react_jsx_runtime.JSX.Element;
3979
+ declare function Sidebar({ children, className, onItemClick, onNewChat, threads, activeThreadId, onSelectThread, onDeleteThread, onRenameThread, primaryColor, }: SidebarProps): react_jsx_runtime.JSX.Element | null;
3966
3980
 
3967
3981
  interface NewChatHeroProps {
3968
3982
  /** The chat input to center, e.g. <ChatInput ... /> */
package/dist/index.js CHANGED
@@ -68142,6 +68142,7 @@ var SuperAtomAuthError = class extends Error {
68142
68142
  super(message);
68143
68143
  this.name = "SuperAtomAuthError";
68144
68144
  this.code = code4;
68145
+ this.reason = options.reason;
68145
68146
  this.status = options.status;
68146
68147
  this.fatal = options.fatal;
68147
68148
  if (options.cause !== void 0) this.cause = options.cause;
@@ -68207,8 +68208,10 @@ var SdkSession = class {
68207
68208
  }
68208
68209
  renew() {
68209
68210
  if (!this.inFlight) {
68211
+ this.opts.onSigningIn?.(true);
68210
68212
  this.inFlight = this.exchange().finally(() => {
68211
68213
  this.inFlight = null;
68214
+ this.opts.onSigningIn?.(false);
68212
68215
  });
68213
68216
  }
68214
68217
  return this.inFlight;
@@ -68243,7 +68246,11 @@ var SdkSession = class {
68243
68246
  const message = typeof body?.error === "string" ? body.error : `Sign-in failed (${res.status})`;
68244
68247
  const fatal = res.status >= 400 && res.status < 500 && res.status !== 429;
68245
68248
  throw this.fail(
68246
- new SuperAtomAuthError(fatal ? "exchange_rejected" : "exchange_unavailable", message, { status: res.status, fatal })
68249
+ new SuperAtomAuthError(fatal ? "exchange_rejected" : "exchange_unavailable", message, {
68250
+ status: res.status,
68251
+ reason: typeof body?.code === "string" ? body.code : void 0,
68252
+ fatal
68253
+ })
68247
68254
  );
68248
68255
  }
68249
68256
  if (typeof body?.token !== "string" || !body.user?.id) {
@@ -69442,6 +69449,8 @@ function resetRegistration() {
69442
69449
  }
69443
69450
  var current = null;
69444
69451
  var retrying = null;
69452
+ var signingIn = false;
69453
+ var chatReady = false;
69445
69454
  var listeners = /* @__PURE__ */ new Set();
69446
69455
  function setAuthStatus(error51) {
69447
69456
  if (current === error51) return;
@@ -69454,6 +69463,36 @@ function setRetryingStatus(error51) {
69454
69463
  retrying = error51;
69455
69464
  listeners.forEach((l) => l());
69456
69465
  }
69466
+ function setSigningIn(value) {
69467
+ if (signingIn === value) return;
69468
+ signingIn = value;
69469
+ listeners.forEach((l) => l());
69470
+ }
69471
+ function useSigningIn() {
69472
+ return useSyncExternalStore(
69473
+ (l) => {
69474
+ listeners.add(l);
69475
+ return () => listeners.delete(l);
69476
+ },
69477
+ () => signingIn,
69478
+ () => false
69479
+ );
69480
+ }
69481
+ function setChatReady(value) {
69482
+ if (chatReady === value) return;
69483
+ chatReady = value;
69484
+ listeners.forEach((l) => l());
69485
+ }
69486
+ function useStartingUp() {
69487
+ return useSyncExternalStore(
69488
+ (l) => {
69489
+ listeners.add(l);
69490
+ return () => listeners.delete(l);
69491
+ },
69492
+ () => !chatReady,
69493
+ () => false
69494
+ );
69495
+ }
69457
69496
  function useRetryingStatus() {
69458
69497
  return useSyncExternalStore(
69459
69498
  (l) => {
@@ -69474,12 +69513,34 @@ function useAuthStatus() {
69474
69513
  () => null
69475
69514
  );
69476
69515
  }
69516
+ var SETUP_REASONS = /* @__PURE__ */ new Set([
69517
+ "bad_request",
69518
+ "bad_project_id",
69519
+ "unknown_project",
69520
+ "bad_sub",
69521
+ "bad_email",
69522
+ "bad_roles",
69523
+ "bad_access",
69524
+ "bad_access_values",
69525
+ "bad_access_filters",
69526
+ "access_not_set_up",
69527
+ "lifetime_too_long",
69528
+ "issued_in_future",
69529
+ "email_linked_elsewhere"
69530
+ ]);
69477
69531
  function authStatusMessage(error51) {
69478
69532
  switch (error51.code) {
69479
69533
  case "get_token_failed":
69480
69534
  return "Your session has ended. Please sign in again to continue.";
69481
69535
  case "exchange_rejected":
69482
- return error51.status === 403 ? "This account cannot use the chat. Please contact your administrator." : "Your session is no longer valid. Please sign in again to continue.";
69536
+ if (error51.reason === "inactive") return "This account has been deactivated.";
69537
+ if (error51.reason === "sdk_not_enabled" || error51.status === 403) {
69538
+ return "This account cannot use the chat. Please contact your administrator.";
69539
+ }
69540
+ if (error51.reason && SETUP_REASONS.has(error51.reason)) {
69541
+ return `This app\u2019s Superatom sign-in is not set up correctly: ${error51.message}`;
69542
+ }
69543
+ return "Your session is no longer valid. Please sign in again to continue.";
69483
69544
  default:
69484
69545
  return "Could not connect to Superatom. Please try again in a moment.";
69485
69546
  }
@@ -69679,6 +69740,7 @@ function useSuperAtom({
69679
69740
  if (sdkSignIn && token) throw new Error("[SuperAtom] Pass either token or getToken, not both");
69680
69741
  const [user, setUser] = useState(null);
69681
69742
  const [authError, setAuthError] = useState(null);
69743
+ const [isSigningIn, setIsSigningIn] = useState(false);
69682
69744
  const [signInAttempt, setSignInAttempt] = useState(0);
69683
69745
  const directUserId = (() => {
69684
69746
  if (sdkSignIn) return void 0;
@@ -69744,7 +69806,13 @@ function useSuperAtom({
69744
69806
  },
69745
69807
  // Superatom unreachable or down, after a couple of tries: say so in the
69746
69808
  // chat instead of sitting on "Connecting…".
69747
- onRetrying: (err) => setRetryingStatus(err)
69809
+ onRetrying: (err) => setRetryingStatus(err),
69810
+ // Lets the chat show "Signing in…" instead of an empty chat while a
69811
+ // sign-in — including one after reconnect() — is in flight.
69812
+ onSigningIn: (value) => {
69813
+ setSigningIn(value);
69814
+ setIsSigningIn(value);
69815
+ }
69748
69816
  });
69749
69817
  sessionRef.current = session;
69750
69818
  for (let delay = 1e3; ; delay = Math.min(delay * 2, 3e4)) {
@@ -69871,6 +69939,7 @@ function useSuperAtom({
69871
69939
  if (!cancelled) {
69872
69940
  setupDoneRef.current = true;
69873
69941
  setBundleReady(true);
69942
+ setChatReady(true);
69874
69943
  }
69875
69944
  } catch (err) {
69876
69945
  console.error("[SuperAtom] Setup failed:", err);
@@ -69890,6 +69959,7 @@ function useSuperAtom({
69890
69959
  setAuthStatus(null);
69891
69960
  setupDoneRef.current = false;
69892
69961
  setBundleReady(false);
69962
+ setChatReady(false);
69893
69963
  };
69894
69964
  }, [directUserId, sdkSignIn, projectId, apiUrl, wsUrl, debug, signInAttempt]);
69895
69965
  const reconnect = useCallback(() => {
@@ -70355,6 +70425,7 @@ function useSuperAtom({
70355
70425
  isNewChat: bundleReady && !isLoadingThread && messages2.length === 0,
70356
70426
  user,
70357
70427
  authError,
70428
+ isSigningIn,
70358
70429
  reconnect
70359
70430
  };
70360
70431
  }
@@ -70452,6 +70523,7 @@ function ChatInput({
70452
70523
  onStop
70453
70524
  }) {
70454
70525
  const authError = useAuthStatus();
70526
+ const startingUp = useStartingUp();
70455
70527
  const isLocked = disabled || !!authError;
70456
70528
  const textareaRef = useRef(null);
70457
70529
  const historyRef = useRef(null);
@@ -70514,6 +70586,7 @@ function ChatInput({
70514
70586
  }, [input, isLocked, onSend, getOrCreateHistory]);
70515
70587
  const themeColor = getThemeColor();
70516
70588
  const effectivePlaceholder = authError ? authStatusMessage(authError) : placeholder;
70589
+ if (startingUp) return null;
70517
70590
  return /* @__PURE__ */ jsx("div", { className: `sa-ui shrink-0 bg-base-100 border-t border-base-300 px-4 py-2 ${className}`, children: /* @__PURE__ */ jsx("div", { className: `group ${isMultiline ? "rounded-3xl" : "rounded-full"} bg-base-200 transition-all duration-200 w-full max-w-2xl mx-auto`, children: /* @__PURE__ */ jsx(
70518
70591
  "div",
70519
70592
  {
@@ -70949,8 +71022,12 @@ function MessageList({
70949
71022
  }, [messages2]);
70950
71023
  const authError = useAuthStatus();
70951
71024
  const retrying2 = useRetryingStatus();
71025
+ const signingIn2 = useSigningIn();
70952
71026
  return /* @__PURE__ */ jsxs("div", { className: `sa-ui flex-1 relative overflow-hidden ${className}`, children: [
70953
- /* @__PURE__ */ jsx("main", { ref: containerRef, className: "h-full overflow-y-auto py-6", children: authError ? /* @__PURE__ */ jsxs("div", { className: "h-full flex flex-col items-center justify-center gap-3 px-6 text-center", children: [
71027
+ /* @__PURE__ */ jsx("main", { ref: containerRef, className: "h-full overflow-y-auto py-6", children: signingIn2 && !bundleReady ? /* @__PURE__ */ jsxs("div", { className: "h-full flex flex-col items-center justify-center gap-3 text-base-content/50", children: [
71028
+ /* @__PURE__ */ jsx("span", { className: "loading loading-spinner loading-lg" }),
71029
+ /* @__PURE__ */ jsx("span", { className: "text-sm", children: "Signing in to Superatom\u2026" })
71030
+ ] }) : authError ? /* @__PURE__ */ jsxs("div", { className: "h-full flex flex-col items-center justify-center gap-3 px-6 text-center", children: [
70954
71031
  /* @__PURE__ */ jsx(Icon, { icon: "mdi:lock-alert-outline", width: 28, height: 28, className: "text-base-content/40" }),
70955
71032
  /* @__PURE__ */ jsx("p", { className: "text-sm text-base-content/70 max-w-sm", children: authStatusMessage(authError) })
70956
71033
  ] }) : !bundleReady || isLoadingThread && messages2.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "h-full flex flex-col items-center justify-center gap-3 text-base-content/50", children: [
@@ -71401,6 +71478,7 @@ function Sidebar({
71401
71478
  setThreadToDelete(null);
71402
71479
  }
71403
71480
  };
71481
+ const startingUp = useStartingUp();
71404
71482
  const [collapsed, setCollapsed] = useState(() => {
71405
71483
  try {
71406
71484
  return localStorage.getItem(SIDEBAR_COLLAPSED_KEY) === "true";
@@ -71485,6 +71563,7 @@ function Sidebar({
71485
71563
  });
71486
71564
  }
71487
71565
  }
71566
+ if (startingUp) return null;
71488
71567
  return /* @__PURE__ */ jsxs(
71489
71568
  "aside",
71490
71569
  {