@bodhiapp/bodhi-js-react 0.0.6 → 0.0.7

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 (32) hide show
  1. package/dist/bodhi-js-sdk/react/src/BodhiProvider.d.ts +7 -34
  2. package/dist/bodhi-js-sdk/react/src/api/index.d.ts +7 -0
  3. package/dist/bodhi-js-sdk/react/src/index.d.ts +6 -12
  4. package/dist/bodhi-react.cjs.js +1 -2
  5. package/dist/bodhi-react.esm.js +40 -471
  6. package/package.json +10 -4
  7. package/README.md +0 -34
  8. package/dist/bodhi-js-sdk/core/src/build-info.d.ts +0 -1
  9. package/dist/bodhi-js-sdk/core/src/direct-client-base.d.ts +0 -129
  10. package/dist/bodhi-js-sdk/core/src/errors.d.ts +0 -22
  11. package/dist/bodhi-js-sdk/core/src/facade-client-base.d.ts +0 -129
  12. package/dist/bodhi-js-sdk/core/src/index.d.ts +0 -20
  13. package/dist/bodhi-js-sdk/core/src/interface.d.ts +0 -235
  14. package/dist/bodhi-js-sdk/core/src/logger.d.ts +0 -12
  15. package/dist/bodhi-js-sdk/core/src/oauth.d.ts +0 -44
  16. package/dist/bodhi-js-sdk/core/src/onboarding/config.d.ts +0 -9
  17. package/dist/bodhi-js-sdk/core/src/onboarding/index.d.ts +0 -5
  18. package/dist/bodhi-js-sdk/core/src/onboarding/modal.d.ts +0 -79
  19. package/dist/bodhi-js-sdk/core/src/onboarding/protocol-utils.d.ts +0 -32
  20. package/dist/bodhi-js-sdk/core/src/platform.d.ts +0 -10
  21. package/dist/bodhi-js-sdk/core/src/storage.d.ts +0 -93
  22. package/dist/bodhi-js-sdk/core/src/types/api.d.ts +0 -33
  23. package/dist/bodhi-js-sdk/core/src/types/auth.d.ts +0 -37
  24. package/dist/bodhi-js-sdk/core/src/types/callback.d.ts +0 -22
  25. package/dist/bodhi-js-sdk/core/src/types/client-state.d.ts +0 -140
  26. package/dist/bodhi-js-sdk/core/src/types/config.d.ts +0 -25
  27. package/dist/bodhi-js-sdk/core/src/types/html.d.ts +0 -9
  28. package/dist/bodhi-js-sdk/core/src/types/index.d.ts +0 -16
  29. package/dist/bodhi-js-sdk/core/src/types/platform.d.ts +0 -15
  30. package/dist/bodhi-js-sdk/core/src/types/user-info.d.ts +0 -27
  31. package/dist/bodhi-js-sdk/react/src/SetupModalProcessor.d.ts +0 -16
  32. package/dist/bodhi-js-sdk/react/src/client-ctx.d.ts +0 -26
@@ -1,35 +1,8 @@
1
- import { AuthState, LogLevel, UIClient } from '../../core/src/index.ts';
2
- import { ReactNode } from 'react';
3
- import { ClientContextState } from './client-ctx';
4
- export type SetupState = 'ready' | 'loading' | 'loaded';
5
- export interface BodhiProviderProps {
6
- children: ReactNode;
7
- client: UIClient;
8
- modalHtmlPath?: string;
9
- handleCallback?: boolean;
10
- callbackPath?: string;
11
- basePath?: string;
12
- logLevel?: LogLevel;
1
+ import { WebUIClientParams } from '../../web/src/index.ts';
2
+ import { BodhiProviderProps as CoreBodhiProviderProps, UIClient } from '../../react-core/src/index.ts';
3
+ export interface BodhiProviderProps extends Omit<CoreBodhiProviderProps, 'client'> {
4
+ authClientId?: string;
5
+ clientConfig?: WebUIClientParams;
6
+ client?: UIClient;
13
7
  }
14
- export interface BodhiContext {
15
- client: UIClient;
16
- clientState: ClientContextState;
17
- setupState: SetupState;
18
- auth: AuthState;
19
- isAuthLoading: boolean;
20
- login: () => Promise<void>;
21
- logout: () => Promise<void>;
22
- showSetup: () => Promise<void>;
23
- hideSetup: () => void;
24
- isAuthenticated: boolean;
25
- canLogin: boolean;
26
- isReady: boolean;
27
- isServerReady: boolean;
28
- isOverallReady: boolean;
29
- isInitializing: boolean;
30
- isExtension: boolean;
31
- isDirect: boolean;
32
- }
33
- export declare const BodhiReactContext: import('react').Context<BodhiContext | null>;
34
- export declare function BodhiProvider({ children, client, modalHtmlPath, handleCallback, callbackPath, basePath, logLevel, }: BodhiProviderProps): import("react/jsx-runtime").JSX.Element;
35
- export declare function useBodhi(): BodhiContext;
8
+ export declare function BodhiProvider({ children, authClientId, clientConfig, client: providedClient, ...restProps }: BodhiProviderProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Re-export all OpenAI-compatible types from @bodhiapp/bodhi-js-core/api
3
+ *
4
+ * Usage:
5
+ * import type { CreateChatCompletionRequest, Model } from '@bodhiapp/bodhi-js-react/api';
6
+ */
7
+ export * from '../../../core/src/index.ts/api';
@@ -1,16 +1,10 @@
1
1
  /**
2
- * @bodhiapp/bodhi-js-react - React bindings for Bodhi SDK
2
+ * @bodhiapp/bodhi-js-react - React bindings for Bodhi Browser SDK (Web preset)
3
3
  *
4
- * Public API exports - minimal surface area following industry best practices
4
+ * Preset package that auto-creates WebUIClient for simplified developer experience.
5
+ * For advanced usage with custom client configuration, use @bodhiapp/bodhi-js-react-core.
5
6
  */
6
- export { BodhiProvider, BodhiReactContext, useBodhi, type BodhiContext, type BodhiProviderProps, type SetupState, } from './BodhiProvider';
7
- export type { ClientContextState, ClientContextStatus } from './client-ctx';
8
- export { INITIAL_CLIENT_CONTEXT_STATE, INITIALIZING_CLIENT_CONTEXT_STATE } from './client-ctx';
9
- export { ClientCtxState, clientStateToContextState, isClientCtxInitialized, isClientCtxInitializing, isClientCtxNotInitialized, isClientCtxReady, isOverallReady, } from './client-ctx';
10
- export type { ApiResponseResult, ClientState } from '../../core/src/index.ts';
11
- export { isApiResultError, isApiResultOperationError, isApiResultSuccess, isDirectState, isExtensionState, isWebUIClient, } from '../../core/src/index.ts';
12
- export { createApiError, createOperationError } from '../../core/src/index.ts';
13
- export type { AuthState, UIClient } from '../../core/src/index.ts';
14
- export { isAuthError, isAuthLoading, isAuthenticated, isClientReady, } from '../../core/src/index.ts';
15
- export { isOperationError, type OperationError } from '../../core/src/index.ts';
7
+ export { BodhiProvider, type BodhiProviderProps } from './BodhiProvider';
8
+ export { WebUIClient, type WebUIClientParams, type IWebUIClient } from '../../web/src/index.ts';
9
+ export { BodhiReactContext, useBodhi, type BodhiContext, type SetupState, type ClientContextState, type ClientContextStatus, INITIAL_CLIENT_CONTEXT_STATE, INITIALIZING_CLIENT_CONTEXT_STATE, ClientCtxState, clientStateToContextState, isClientCtxInitialized, isClientCtxInitializing, isClientCtxNotInitialized, isClientCtxReady, isOverallReady, type ApiResponseResult, type ClientState, type AuthState, type UIClient, type OperationError, isApiResultError, isApiResultOperationError, isApiResultSuccess, isDirectState, isExtensionState, isWebUIClient, isAuthError, isAuthLoading, isAuthenticated, isClientReady, isOperationError, createApiError, createOperationError, } from '../../react-core/src/index.ts';
16
10
  export { BUILD_MODE as REACT_BUILD_MODE } from './build-info';
@@ -1,2 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const k=require("react/jsx-runtime"),s=require("@bodhiapp/bodhi-js-core"),r=require("react"),p={MODAL_READY:"modal:ready",MODAL_REFRESH:"modal:refresh",MODAL_CLOSE:"modal:close",MODAL_COMPLETE:"modal:complete",MODAL_LNA_CONNECT:"modal:lna:connect",MODAL_LNA_SKIP:"modal:lna:skip",MODAL_CONFIRM_SERVER_INSTALL:"modal:confirm-server-install",MODAL_SELECT_CONNECTION:"modal:select-connection"};function H({client:e,modalHtmlPath:i,hideSetup:L,onSetupReady:x,setupState:R,basePath:m="/",logLevel:A="warn"}){const y=R!=="ready",O=r.useMemo(()=>new s.Logger("SetupModalProcessor",A),[A]),l=r.useRef(null),u=r.useMemo(()=>new s.BodhiClientUserPrefsManager(s.createStoragePrefixWithBasePath(m,"bodhijs:")),[m]),C=r.useRef(null),E=r.useCallback(t=>t==="direct"?"lna":t==="extension"?"extension":null,[]),v=r.useCallback(t=>t.extension==="ready"?{status:"ready",version:"unknown",id:t.extensionId}:t.extension==="not-found"?{status:"not-installed",error:{message:"Extension not found",code:"ext-not-installed"}}:{status:"unreachable",error:{message:"Client not initialized",code:"ext-connection-failed"}},[]),b=r.useCallback(t=>{if(t.server.status==="pending-extension-ready")return{status:"pending-extension-ready",error:{message:"Extension not ready",code:"server-pending-ext-ready"}};const n=t.server;switch(n.status){case"ready":return{status:"ready",version:n.version||"unknown"};case"setup":return{status:"setup",version:n.version||"unknown",error:{message:n.error?.message||"Setup required",code:"server-in-setup-status"}};case"resource-admin":return{status:"resource-admin",version:n.version||"unknown",error:{message:n.error?.message||"Resource admin required",code:"server-in-admin-status"}};case"error":return{status:"error",error:{message:n.error?.message||"Unknown error",code:"server-unexpected-error"}};case"not-reachable":return{status:"unreachable",error:{message:n.error?.message||"Server not reachable",code:"server-conn-refused"}};default:return{status:"unreachable",error:{message:"Unknown server status",code:"server-unexpected-error"}}}},[]),g=r.useCallback(t=>{if(t.server.status==="not-connected")return{status:"pending-lna-ready"};const n=t.server;switch(n.status){case"ready":return{status:"ready",version:n.version||"unknown"};case"setup":return{status:"setup",version:n.version||"unknown"};case"resource-admin":return{status:"resource-admin",version:n.version||"unknown"};case"error":case"not-reachable":return{status:"error",error:{message:n.error?.message||"Connection error"}};default:return{status:"error",error:{message:"Unknown server status"}}}},[]),I=r.useCallback((t,n)=>{if(t.server.status!=="pending-extension-ready"){const o=t.server.status;if(o==="ready"||o==="setup"||o==="resource-admin")return!0}if(n.server.status!=="not-connected"){const o=n.server.status;if(o==="ready"||o==="setup"||o==="resource-admin")return!0}return!1},[]),h=r.useCallback((t,n,o)=>{if(n==="skipped")return{status:"skipped",serverUrl:o};if(t.server.status!=="not-connected"){const d=t.server;return d.status==="ready"||d.status==="setup"||d.status==="resource-admin"?{status:"granted",serverUrl:o}:{status:"unreachable",serverUrl:o,error:{message:d.error?.message||"Server unreachable",code:"lna-unreachable"}}}return n==="granted"?{status:"granted",serverUrl:o}:{status:"prompt",serverUrl:o}},[]),S=r.useCallback(async(t=!1)=>{const n=s.detectBrowser().type,o=s.detectOS().type;let d=await e.getExtensionState();(d.extension==="not-initialized"||t)&&(d=await e.testExtensionConnectivity());let a=await e.getDirectState();const c=u.getDirectStatus();c==="granted"&&(a.server.status==="not-connected"||t)&&(a=await e.testDirectConnectivity());const w=s.getServerUrl(a)||"http://localhost:1135",_=h(a,c,w);return e.getConnectionMode()===null&&(s.isDirectServerReady(a)?await e.setConnectionMode("direct"):s.isExtensionServerReady(d)&&await e.setConnectionMode("extension")),u.isServerInstallConfirmed()||I(d,a)&&u.setServerInstallConfirmed(!0),{extension:v(d),server:b(d),lna:_,lnaServer:g(a),env:{browser:n,os:o},browsers:s.BROWSER_CONFIGS,os:s.OS_CONFIGS,userConfirmations:{serverInstall:u.isServerInstallConfirmed()},selectedConnection:E(e.getConnectionMode())}},[e,u,v,b,g,E,h,I]),f=r.useCallback(()=>{if(!C.current)throw new Error("Cannot get state: currentStateRef is null");return{...C.current,userConfirmations:{serverInstall:u.isServerInstallConfirmed()},selectedConnection:E(e.getConnectionMode())}},[u,e,E]),T=r.useMemo(()=>({[p.MODAL_READY]:async()=>(O.info("MODAL_READY: building initial state"),{setupState:f()}),[p.MODAL_REFRESH]:async()=>{O.info("MODAL_REFRESH: refreshing state");const t=await S(!0);C.current=t;const n=f();return O.info(`MODAL_REFRESH: state refreshed
2
- `,JSON.stringify(n,null,2)),l.current?.updateState(f()),{setupState:n}},[p.MODAL_LNA_CONNECT]:async t=>{const n=t.payload.serverUrl;console.log("[SetupModalProcessor] LNA connect:",n);const o=await e.testDirectConnectivity(n);if(o.server.status!=="not-connected"){const a=o.server.status;if(a==="ready"||a==="setup"||a==="resource-admin"){u.setDirectStatus("granted"),e.getConnectionMode()===null&&await e.setConnectionMode("direct");const c=await S();return C.current=c,l.current?.updateState(f()),{success:!0}}}const d=await S();return C.current=d,l.current?.updateState(f()),{success:!1}},[p.MODAL_LNA_SKIP]:async()=>{u.setDirectStatus("skipped");const t=await S();return C.current=t,l.current?.updateState(f()),{success:!0}},[p.MODAL_CLOSE]:()=>{L()},[p.MODAL_COMPLETE]:()=>{L()},[p.MODAL_CONFIRM_SERVER_INSTALL]:t=>(u.setServerInstallConfirmed(t.payload.confirmed),l.current?.updateState(f()),{success:!0}),[p.MODAL_SELECT_CONNECTION]:async t=>{const o=t.payload.connection==="lna"?"direct":"extension";return await e.setConnectionMode(o),l.current?.updateState(f()),{success:!0}}}),[O,e,u,S,f,g,L]);return r.useEffect(()=>(l.current=new s.OnboardingModal({modalHtmlPath:i,handlers:T}),()=>{l.current?.destroy(),l.current=null}),[i,T]),r.useEffect(()=>{y&&l.current?S(!0).then(t=>{C.current=t,l.current?.show(t),x?.()}).catch(t=>{console.error("[SetupModalProcessor] buildSetupState failed:",t)}):!y&&l.current&&l.current.destroy()},[y,S,x]),null}const P={status:"not-initialized",mode:null,extensionId:null,url:null,server:s.BACKEND_SERVER_NOT_CONNECTED,error:null},z={status:"initializing",mode:null,extensionId:null,url:null,server:s.BACKEND_SERVER_NOT_CONNECTED,error:null};function B(e){return e.status==="not-initialized"}function j(e){return e.status==="initializing"}function U(e){return e.status!=="not-initialized"&&e.status!=="initializing"}function D(e){return e.status==="ready"}function F(e){return D(e)&&e.server.status==="ready"}function G(e){return s.isExtensionState(e)?{status:e.extension==="not-initialized"?"initializing":e.extension==="not-found"?"extension-not-found":"ready",mode:"extension",extensionId:e.extensionId,url:null,server:e.server,error:e.server.error}:{status:e.url===null?"direct-not-connected":"ready",mode:"direct",extensionId:null,url:e.url,server:e.server,error:e.server.error}}const K={isNotInitialized:B,isInitializing:j,isInitialized:U,isReady:D,isOverallReady:F},N=r.createContext(null);N.displayName="BodhiContext";function V({children:e,client:i,modalHtmlPath:L,handleCallback:x=!0,callbackPath:R="/callback",basePath:m="/",logLevel:A="warn"}){const y=r.useMemo(()=>new s.Logger("BodhiProvider",A),[A]),O=r.useRef(!1),l=r.useRef(!1),[u,C]=r.useState(P),[E,v]=r.useState(s.INITIAL_AUTH_STATE),[b,g]=r.useState(!1),[I,h]=r.useState("ready");r.useEffect(()=>{const a=c=>{switch(c.type){case"client-state":C(G(c.state));break;case"auth-state":v(c.state),g(!1);break}};return i.setStateCallback(a),()=>{i.setStateCallback(s.NOOP_STATE_CALLBACK)}},[i]);const S=r.useCallback(async()=>{h("loading")},[]),f=r.useCallback(()=>{h("ready")},[]),T=r.useCallback(()=>{h("loaded")},[]),t=r.useCallback(async a=>{C(z);try{await i.init(a||{})}catch(c){y.error("Init failed:",c)}},[i,y]);r.useEffect(()=>{if(l.current)return;l.current=!0,(async()=>{if(await t(),!x)return;const c=new URL(window.location.href);if(c.pathname!==R)return;const M=c.searchParams.get("code"),w=c.searchParams.get("state");!M||!w||O.current||(O.current=!0,s.isWebUIClient(i)&&(g(!0),i.handleOAuthCallback(M,w).then(()=>{window.history.replaceState({},"",m)}).catch(_=>{y.error("OAuth callback failed:",_),v({status:"error",user:null,accessToken:null,error:{message:_ instanceof Error?_.message:"OAuth callback failed",code:"OAUTH_CALLBACK_FAILED"}}),g(!1),window.history.replaceState({},"",m)})))})()},[t,i,x,R,m]);const n=r.useCallback(async()=>{g(!0);try{await i.login()}catch(a){v({status:"error",user:null,accessToken:null,error:{message:a instanceof Error?a.message:"Login failed",code:"LOGIN_FAILED"}}),g(!1)}},[i]),o=r.useCallback(async()=>{try{await i.logout()}catch(a){v({status:"error",user:null,accessToken:null,error:{message:a instanceof Error?a.message:"Logout failed",code:"LOGOUT_FAILED"}})}},[i]),d=r.useMemo(()=>{const a=u.status==="ready",c=u.server.status==="ready";return{client:i,clientState:u,auth:E,isAuthLoading:b,login:n,logout:o,showSetup:S,hideSetup:f,setupState:I,isAuthenticated:E.status==="authenticated",canLogin:a&&!b,isReady:a,isServerReady:c,isOverallReady:a&&c,isInitializing:u.status==="initializing",isExtension:u.mode==="extension",isDirect:u.mode==="direct"}},[i,u,E,b,I,n,o,S,f]);return k.jsxs(N.Provider,{value:d,children:[k.jsx(H,{client:i,modalHtmlPath:L,hideSetup:f,onSetupReady:T,setupState:I,basePath:m,logLevel:A}),e]})}function W(){const e=r.useContext(N);if(!e)throw new Error("useBodhi must be used within BodhiProvider");return e}const q="production";Object.defineProperty(exports,"createApiError",{enumerable:!0,get:()=>s.createApiError});Object.defineProperty(exports,"createOperationError",{enumerable:!0,get:()=>s.createOperationError});Object.defineProperty(exports,"isApiResultError",{enumerable:!0,get:()=>s.isApiResultError});Object.defineProperty(exports,"isApiResultOperationError",{enumerable:!0,get:()=>s.isApiResultOperationError});Object.defineProperty(exports,"isApiResultSuccess",{enumerable:!0,get:()=>s.isApiResultSuccess});Object.defineProperty(exports,"isAuthError",{enumerable:!0,get:()=>s.isAuthError});Object.defineProperty(exports,"isAuthLoading",{enumerable:!0,get:()=>s.isAuthLoading});Object.defineProperty(exports,"isAuthenticated",{enumerable:!0,get:()=>s.isAuthenticated});Object.defineProperty(exports,"isClientReady",{enumerable:!0,get:()=>s.isClientReady});Object.defineProperty(exports,"isDirectState",{enumerable:!0,get:()=>s.isDirectState});Object.defineProperty(exports,"isExtensionState",{enumerable:!0,get:()=>s.isExtensionState});Object.defineProperty(exports,"isOperationError",{enumerable:!0,get:()=>s.isOperationError});Object.defineProperty(exports,"isWebUIClient",{enumerable:!0,get:()=>s.isWebUIClient});exports.BodhiProvider=V;exports.BodhiReactContext=N;exports.ClientCtxState=K;exports.INITIALIZING_CLIENT_CONTEXT_STATE=z;exports.INITIAL_CLIENT_CONTEXT_STATE=P;exports.REACT_BUILD_MODE=q;exports.clientStateToContextState=G;exports.isClientCtxInitialized=U;exports.isClientCtxInitializing=j;exports.isClientCtxNotInitialized=B;exports.isClientCtxReady=D;exports.isOverallReady=F;exports.useBodhi=W;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("react/jsx-runtime"),u=require("react"),o=require("@bodhiapp/bodhi-js"),e=require("@bodhiapp/bodhi-js-react-core");function b({children:a,authClientId:i,clientConfig:n,client:t,...l}){if(!t&&!i)throw new Error('BodhiProvider requires either "client" or "authClientId" prop');const r=u.useRef(null),s=u.useMemo(()=>t||(r.current||(r.current=new o.WebUIClient(i,n)),r.current),[t,i,n]);return c.jsx(e.BodhiProvider,{client:s,...l,children:a})}const d="production";Object.defineProperty(exports,"WebUIClient",{enumerable:!0,get:()=>o.WebUIClient});Object.defineProperty(exports,"BodhiReactContext",{enumerable:!0,get:()=>e.BodhiReactContext});Object.defineProperty(exports,"ClientCtxState",{enumerable:!0,get:()=>e.ClientCtxState});Object.defineProperty(exports,"INITIALIZING_CLIENT_CONTEXT_STATE",{enumerable:!0,get:()=>e.INITIALIZING_CLIENT_CONTEXT_STATE});Object.defineProperty(exports,"INITIAL_CLIENT_CONTEXT_STATE",{enumerable:!0,get:()=>e.INITIAL_CLIENT_CONTEXT_STATE});Object.defineProperty(exports,"clientStateToContextState",{enumerable:!0,get:()=>e.clientStateToContextState});Object.defineProperty(exports,"createApiError",{enumerable:!0,get:()=>e.createApiError});Object.defineProperty(exports,"createOperationError",{enumerable:!0,get:()=>e.createOperationError});Object.defineProperty(exports,"isApiResultError",{enumerable:!0,get:()=>e.isApiResultError});Object.defineProperty(exports,"isApiResultOperationError",{enumerable:!0,get:()=>e.isApiResultOperationError});Object.defineProperty(exports,"isApiResultSuccess",{enumerable:!0,get:()=>e.isApiResultSuccess});Object.defineProperty(exports,"isAuthError",{enumerable:!0,get:()=>e.isAuthError});Object.defineProperty(exports,"isAuthLoading",{enumerable:!0,get:()=>e.isAuthLoading});Object.defineProperty(exports,"isAuthenticated",{enumerable:!0,get:()=>e.isAuthenticated});Object.defineProperty(exports,"isClientCtxInitialized",{enumerable:!0,get:()=>e.isClientCtxInitialized});Object.defineProperty(exports,"isClientCtxInitializing",{enumerable:!0,get:()=>e.isClientCtxInitializing});Object.defineProperty(exports,"isClientCtxNotInitialized",{enumerable:!0,get:()=>e.isClientCtxNotInitialized});Object.defineProperty(exports,"isClientCtxReady",{enumerable:!0,get:()=>e.isClientCtxReady});Object.defineProperty(exports,"isClientReady",{enumerable:!0,get:()=>e.isClientReady});Object.defineProperty(exports,"isDirectState",{enumerable:!0,get:()=>e.isDirectState});Object.defineProperty(exports,"isExtensionState",{enumerable:!0,get:()=>e.isExtensionState});Object.defineProperty(exports,"isOperationError",{enumerable:!0,get:()=>e.isOperationError});Object.defineProperty(exports,"isOverallReady",{enumerable:!0,get:()=>e.isOverallReady});Object.defineProperty(exports,"isWebUIClient",{enumerable:!0,get:()=>e.isWebUIClient});Object.defineProperty(exports,"useBodhi",{enumerable:!0,get:()=>e.useBodhi});exports.BodhiProvider=b;exports.REACT_BUILD_MODE=d;
@@ -1,473 +1,42 @@
1
- import { jsxs as F, jsx as H } from "react/jsx-runtime";
2
- import { Logger as B, BodhiClientUserPrefsManager as G, createStoragePrefixWithBasePath as K, detectBrowser as V, detectOS as W, getServerUrl as j, isDirectServerReady as Y, isExtensionServerReady as q, OS_CONFIGS as X, BROWSER_CONFIGS as J, OnboardingModal as Z, BACKEND_SERVER_NOT_CONNECTED as P, isExtensionState as Q, INITIAL_AUTH_STATE as $, NOOP_STATE_CALLBACK as ee, isWebUIClient as te } from "@bodhiapp/bodhi-js-core";
3
- import { createApiError as Ae, createOperationError as Oe, isApiResultError as Le, isApiResultOperationError as he, isApiResultSuccess as we, isAuthError as xe, isAuthLoading as Ie, isAuthenticated as _e, isClientReady as Re, isDirectState as De, isExtensionState as Me, isOperationError as Ne, isWebUIClient as Te } from "@bodhiapp/bodhi-js-core";
4
- import { useMemo as _, useRef as T, useCallback as d, useEffect as b, createContext as re, useState as N, useContext as ne } from "react";
5
- const m = {
6
- // Modal lifecycle
7
- MODAL_READY: "modal:ready",
8
- MODAL_REFRESH: "modal:refresh",
9
- MODAL_CLOSE: "modal:close",
10
- MODAL_COMPLETE: "modal:complete",
11
- // LNA actions
12
- MODAL_LNA_CONNECT: "modal:lna:connect",
13
- MODAL_LNA_SKIP: "modal:lna:skip",
14
- // Server confirmation
15
- MODAL_CONFIRM_SERVER_INSTALL: "modal:confirm-server-install",
16
- // Connection selection
17
- MODAL_SELECT_CONNECTION: "modal:select-connection"
18
- };
19
- function se({
20
- client: e,
21
- modalHtmlPath: o,
22
- hideSetup: w,
23
- onSetupReady: x,
24
- setupState: R,
25
- basePath: g = "/",
26
- logLevel: A = "warn"
27
- }) {
28
- const p = R !== "ready", E = _(() => new B("SetupModalProcessor", A), [A]), u = T(null), a = _(
29
- () => new G(K(g, "bodhijs:")),
30
- [g]
31
- ), f = T(null), v = d(
32
- (t) => t === "direct" ? "lna" : t === "extension" ? "extension" : null,
33
- []
34
- ), y = d((t) => t.extension === "ready" ? {
35
- status: "ready",
36
- version: "unknown",
37
- // TODO: have ExtensionState also get extension version
38
- id: t.extensionId
39
- } : t.extension === "not-found" ? {
40
- status: "not-installed",
41
- error: { message: "Extension not found", code: "ext-not-installed" }
42
- } : {
43
- status: "unreachable",
44
- error: { message: "Client not initialized", code: "ext-connection-failed" }
45
- }, []), O = d((t) => {
46
- if (t.server.status === "pending-extension-ready")
47
- return {
48
- status: "pending-extension-ready",
49
- error: { message: "Extension not ready", code: "server-pending-ext-ready" }
50
- };
51
- const r = t.server;
52
- switch (r.status) {
53
- case "ready":
54
- return { status: "ready", version: r.version || "unknown" };
55
- case "setup":
56
- return {
57
- status: "setup",
58
- version: r.version || "unknown",
59
- error: {
60
- message: r.error?.message || "Setup required",
61
- code: "server-in-setup-status"
62
- }
63
- };
64
- case "resource-admin":
65
- return {
66
- status: "resource-admin",
67
- version: r.version || "unknown",
68
- error: {
69
- message: r.error?.message || "Resource admin required",
70
- code: "server-in-admin-status"
71
- }
72
- };
73
- case "error":
74
- return {
75
- status: "error",
76
- error: {
77
- message: r.error?.message || "Unknown error",
78
- code: "server-unexpected-error"
79
- }
80
- };
81
- case "not-reachable":
82
- return {
83
- status: "unreachable",
84
- error: {
85
- message: r.error?.message || "Server not reachable",
86
- code: "server-conn-refused"
87
- }
88
- };
89
- default:
90
- return {
91
- status: "unreachable",
92
- error: {
93
- message: "Unknown server status",
94
- code: "server-unexpected-error"
95
- }
96
- };
97
- }
98
- }, []), C = d((t) => {
99
- if (t.server.status === "not-connected")
100
- return { status: "pending-lna-ready" };
101
- const r = t.server;
102
- switch (r.status) {
103
- case "ready":
104
- return { status: "ready", version: r.version || "unknown" };
105
- case "setup":
106
- return { status: "setup", version: r.version || "unknown" };
107
- case "resource-admin":
108
- return { status: "resource-admin", version: r.version || "unknown" };
109
- case "error":
110
- case "not-reachable":
111
- return {
112
- status: "error",
113
- error: { message: r.error?.message || "Connection error" }
114
- };
115
- default:
116
- return {
117
- status: "error",
118
- error: { message: "Unknown server status" }
119
- };
120
- }
121
- }, []), L = d(
122
- (t, r) => {
123
- if (t.server.status !== "pending-extension-ready") {
124
- const s = t.server.status;
125
- if (s === "ready" || s === "setup" || s === "resource-admin")
126
- return !0;
127
- }
128
- if (r.server.status !== "not-connected") {
129
- const s = r.server.status;
130
- if (s === "ready" || s === "setup" || s === "resource-admin")
131
- return !0;
132
- }
133
- return !1;
134
- },
135
- []
136
- ), h = d(
137
- (t, r, s) => {
138
- if (r === "skipped")
139
- return { status: "skipped", serverUrl: s };
140
- if (t.server.status !== "not-connected") {
141
- const c = t.server;
142
- return c.status === "ready" || c.status === "setup" || c.status === "resource-admin" ? { status: "granted", serverUrl: s } : {
143
- status: "unreachable",
144
- serverUrl: s,
145
- error: {
146
- message: c.error?.message || "Server unreachable",
147
- code: "lna-unreachable"
148
- }
149
- };
150
- }
151
- return r === "granted" ? { status: "granted", serverUrl: s } : { status: "prompt", serverUrl: s };
152
- },
153
- []
154
- ), S = d(
155
- async (t = !1) => {
156
- const r = V().type, s = W().type;
157
- let c = await e.getExtensionState();
158
- (c.extension === "not-initialized" || t) && (c = await e.testExtensionConnectivity());
159
- let n = await e.getDirectState();
160
- const i = a.getDirectStatus();
161
- i === "granted" && (n.server.status === "not-connected" || t) && (n = await e.testDirectConnectivity());
162
- const M = j(n) || "http://localhost:1135", I = h(n, i, M);
163
- return e.getConnectionMode() === null && (Y(n) ? await e.setConnectionMode("direct") : q(c) && await e.setConnectionMode("extension")), a.isServerInstallConfirmed() || L(c, n) && a.setServerInstallConfirmed(!0), {
164
- extension: y(c),
165
- server: O(c),
166
- lna: I,
167
- lnaServer: C(n),
168
- env: { browser: r, os: s },
169
- browsers: J,
170
- os: X,
171
- userConfirmations: { serverInstall: a.isServerInstallConfirmed() },
172
- selectedConnection: v(e.getConnectionMode())
173
- };
174
- },
175
- [
176
- e,
177
- a,
178
- y,
179
- O,
180
- C,
181
- v,
182
- h,
183
- L
184
- ]
185
- ), l = d(() => {
186
- if (!f.current)
187
- throw new Error("Cannot get state: currentStateRef is null");
188
- return {
189
- ...f.current,
190
- // Override userConfirmations from storage (in case updated outside buildSetupState)
191
- userConfirmations: {
192
- serverInstall: a.isServerInstallConfirmed()
193
- },
194
- // Override selectedConnection from client (in case changed via handler)
195
- selectedConnection: v(e.getConnectionMode())
196
- };
197
- }, [a, e, v]), D = _(
198
- () => ({
199
- [m.MODAL_READY]: async () => (E.info("MODAL_READY: building initial state"), { setupState: l() }),
200
- [m.MODAL_REFRESH]: async () => {
201
- E.info("MODAL_REFRESH: refreshing state");
202
- const t = await S(!0);
203
- f.current = t;
204
- const r = l();
205
- return E.info(`MODAL_REFRESH: state refreshed
206
- `, JSON.stringify(r, null, 2)), u.current?.updateState(l()), { setupState: r };
207
- },
208
- [m.MODAL_LNA_CONNECT]: async (t) => {
209
- const r = t.payload.serverUrl;
210
- console.log("[SetupModalProcessor] LNA connect:", r);
211
- const s = await e.testDirectConnectivity(r);
212
- if (s.server.status !== "not-connected") {
213
- const n = s.server.status;
214
- if (n === "ready" || n === "setup" || n === "resource-admin") {
215
- a.setDirectStatus("granted"), e.getConnectionMode() === null && await e.setConnectionMode("direct");
216
- const i = await S();
217
- return f.current = i, u.current?.updateState(l()), { success: !0 };
218
- }
219
- }
220
- const c = await S();
221
- return f.current = c, u.current?.updateState(l()), { success: !1 };
222
- },
223
- [m.MODAL_LNA_SKIP]: async () => {
224
- a.setDirectStatus("skipped");
225
- const t = await S();
226
- return f.current = t, u.current?.updateState(l()), { success: !0 };
227
- },
228
- [m.MODAL_CLOSE]: () => {
229
- w();
230
- },
231
- [m.MODAL_COMPLETE]: () => {
232
- w();
233
- },
234
- [m.MODAL_CONFIRM_SERVER_INSTALL]: (t) => (a.setServerInstallConfirmed(t.payload.confirmed), u.current?.updateState(l()), { success: !0 }),
235
- [m.MODAL_SELECT_CONNECTION]: async (t) => {
236
- const s = t.payload.connection === "lna" ? "direct" : "extension";
237
- return await e.setConnectionMode(s), u.current?.updateState(l()), { success: !0 };
238
- }
239
- }),
240
- [E, e, a, S, l, C, w]
241
- );
242
- return b(() => (u.current = new Z({ modalHtmlPath: o, handlers: D }), () => {
243
- u.current?.destroy(), u.current = null;
244
- }), [o, D]), b(() => {
245
- p && u.current ? S(!0).then((t) => {
246
- f.current = t, u.current?.show(t), x?.();
247
- }).catch((t) => {
248
- console.error("[SetupModalProcessor] buildSetupState failed:", t);
249
- }) : !p && u.current && u.current.destroy();
250
- }, [p, S, x]), null;
251
- }
252
- const oe = {
253
- status: "not-initialized",
254
- mode: null,
255
- extensionId: null,
256
- url: null,
257
- server: P,
258
- error: null
259
- }, ae = {
260
- status: "initializing",
261
- mode: null,
262
- extensionId: null,
263
- url: null,
264
- server: P,
265
- error: null
266
- };
267
- function ie(e) {
268
- return e.status === "not-initialized";
269
- }
270
- function ue(e) {
271
- return e.status === "initializing";
272
- }
273
- function ce(e) {
274
- return e.status !== "not-initialized" && e.status !== "initializing";
275
- }
276
- function U(e) {
277
- return e.status === "ready";
278
- }
279
- function de(e) {
280
- return U(e) && e.server.status === "ready";
281
- }
282
- function le(e) {
283
- return Q(e) ? {
284
- status: e.extension === "not-initialized" ? "initializing" : e.extension === "not-found" ? "extension-not-found" : "ready",
285
- mode: "extension",
286
- extensionId: e.extensionId,
287
- url: null,
288
- server: e.server,
289
- error: e.server.error
290
- } : {
291
- status: e.url === null ? "direct-not-connected" : "ready",
292
- mode: "direct",
293
- extensionId: null,
294
- url: e.url,
295
- server: e.server,
296
- error: e.server.error
297
- };
298
- }
299
- const ve = {
300
- isNotInitialized: ie,
301
- isInitializing: ue,
302
- isInitialized: ce,
303
- isReady: U,
304
- isOverallReady: de
305
- }, z = re(null);
306
- z.displayName = "BodhiContext";
307
- function me({
308
- children: e,
309
- client: o,
310
- modalHtmlPath: w,
311
- handleCallback: x = !0,
312
- callbackPath: R = "/callback",
313
- basePath: g = "/",
314
- logLevel: A = "warn"
315
- }) {
316
- const p = _(() => new B("BodhiProvider", A), [A]), E = T(!1), u = T(!1), [a, f] = N(oe), [v, y] = N($), [O, C] = N(!1), [L, h] = N("ready");
317
- b(() => {
318
- const n = (i) => {
319
- switch (i.type) {
320
- case "client-state":
321
- f(le(i.state));
322
- break;
323
- case "auth-state":
324
- y(i.state), C(!1);
325
- break;
326
- }
327
- };
328
- return o.setStateCallback(n), () => {
329
- o.setStateCallback(ee);
330
- };
331
- }, [o]);
332
- const S = d(async () => {
333
- h("loading");
334
- }, []), l = d(() => {
335
- h("ready");
336
- }, []), D = d(() => {
337
- h("loaded");
338
- }, []), t = d(
339
- async (n) => {
340
- f(ae);
341
- try {
342
- await o.init(n || {});
343
- } catch (i) {
344
- p.error("Init failed:", i);
345
- }
346
- },
347
- [o, p]
348
- );
349
- b(() => {
350
- if (u.current) return;
351
- u.current = !0, (async () => {
352
- if (await t(), !x) return;
353
- const i = new URL(window.location.href);
354
- if (i.pathname !== R) return;
355
- const k = i.searchParams.get("code"), M = i.searchParams.get("state");
356
- !k || !M || E.current || (E.current = !0, te(o) && (C(!0), o.handleOAuthCallback(k, M).then(() => {
357
- window.history.replaceState({}, "", g);
358
- }).catch((I) => {
359
- p.error("OAuth callback failed:", I), y({
360
- status: "error",
361
- user: null,
362
- accessToken: null,
363
- error: {
364
- message: I instanceof Error ? I.message : "OAuth callback failed",
365
- code: "OAUTH_CALLBACK_FAILED"
366
- }
367
- }), C(!1), window.history.replaceState({}, "", g);
368
- })));
369
- })();
370
- }, [t, o, x, R, g]);
371
- const r = d(async () => {
372
- C(!0);
373
- try {
374
- await o.login();
375
- } catch (n) {
376
- y({
377
- status: "error",
378
- user: null,
379
- accessToken: null,
380
- error: {
381
- message: n instanceof Error ? n.message : "Login failed",
382
- code: "LOGIN_FAILED"
383
- }
384
- }), C(!1);
385
- }
386
- }, [o]), s = d(async () => {
387
- try {
388
- await o.logout();
389
- } catch (n) {
390
- y({
391
- status: "error",
392
- user: null,
393
- accessToken: null,
394
- error: {
395
- message: n instanceof Error ? n.message : "Logout failed",
396
- code: "LOGOUT_FAILED"
397
- }
398
- });
399
- }
400
- }, [o]), c = _(() => {
401
- const n = a.status === "ready", i = a.server.status === "ready";
402
- return {
403
- client: o,
404
- clientState: a,
405
- auth: v,
406
- isAuthLoading: O,
407
- login: r,
408
- logout: s,
409
- showSetup: S,
410
- hideSetup: l,
411
- setupState: L,
412
- // Computed auth properties
413
- isAuthenticated: v.status === "authenticated",
414
- canLogin: n && !O,
415
- // Computed connection properties
416
- isReady: n,
417
- isServerReady: i,
418
- isOverallReady: n && i,
419
- isInitializing: a.status === "initializing",
420
- isExtension: a.mode === "extension",
421
- isDirect: a.mode === "direct"
422
- };
423
- }, [o, a, v, O, L, r, s, S, l]);
424
- return /* @__PURE__ */ F(z.Provider, { value: c, children: [
425
- /* @__PURE__ */ H(
426
- se,
427
- {
428
- client: o,
429
- modalHtmlPath: w,
430
- hideSetup: l,
431
- onSetupReady: D,
432
- setupState: L,
433
- basePath: g,
434
- logLevel: A
435
- }
436
- ),
437
- e
438
- ] });
439
- }
440
- function ge() {
441
- const e = ne(z);
442
- if (!e) throw new Error("useBodhi must be used within BodhiProvider");
443
- return e;
444
- }
445
- const pe = "production";
1
+ import { jsx as a } from "react/jsx-runtime";
2
+ import { useRef as u, useMemo as c } from "react";
3
+ import { WebUIClient as l } from "@bodhiapp/bodhi-js";
4
+ import { WebUIClient as m } from "@bodhiapp/bodhi-js";
5
+ import { BodhiProvider as E } from "@bodhiapp/bodhi-js-react-core";
6
+ import { BodhiReactContext as R, ClientCtxState as _, INITIALIZING_CLIENT_CONTEXT_STATE as B, INITIAL_CLIENT_CONTEXT_STATE as N, clientStateToContextState as O, createApiError as S, createOperationError as L, isApiResultError as D, isApiResultOperationError as U, isApiResultSuccess as P, isAuthError as b, isAuthLoading as w, isAuthenticated as y, isClientCtxInitialized as z, isClientCtxInitializing as M, isClientCtxNotInitialized as W, isClientCtxReady as v, isClientReady as X, isDirectState as g, isExtensionState as j, isOperationError as q, isOverallReady as G, isWebUIClient as Z, useBodhi as $ } from "@bodhiapp/bodhi-js-react-core";
7
+ function x({ children: o, authClientId: e, clientConfig: i, client: r, ...n }) {
8
+ if (!r && !e)
9
+ throw new Error('BodhiProvider requires either "client" or "authClientId" prop');
10
+ const t = u(null), s = c(() => r || (t.current || (t.current = new l(e, i)), t.current), [r, e, i]);
11
+ return /* @__PURE__ */ a(E, { client: s, ...n, children: o });
12
+ }
13
+ const A = "production";
446
14
  export {
447
- me as BodhiProvider,
448
- z as BodhiReactContext,
449
- ve as ClientCtxState,
450
- ae as INITIALIZING_CLIENT_CONTEXT_STATE,
451
- oe as INITIAL_CLIENT_CONTEXT_STATE,
452
- pe as REACT_BUILD_MODE,
453
- le as clientStateToContextState,
454
- Ae as createApiError,
455
- Oe as createOperationError,
456
- Le as isApiResultError,
457
- he as isApiResultOperationError,
458
- we as isApiResultSuccess,
459
- xe as isAuthError,
460
- Ie as isAuthLoading,
461
- _e as isAuthenticated,
462
- ce as isClientCtxInitialized,
463
- ue as isClientCtxInitializing,
464
- ie as isClientCtxNotInitialized,
465
- U as isClientCtxReady,
466
- Re as isClientReady,
467
- De as isDirectState,
468
- Me as isExtensionState,
469
- Ne as isOperationError,
470
- de as isOverallReady,
471
- Te as isWebUIClient,
472
- ge as useBodhi
15
+ x as BodhiProvider,
16
+ R as BodhiReactContext,
17
+ _ as ClientCtxState,
18
+ B as INITIALIZING_CLIENT_CONTEXT_STATE,
19
+ N as INITIAL_CLIENT_CONTEXT_STATE,
20
+ A as REACT_BUILD_MODE,
21
+ m as WebUIClient,
22
+ O as clientStateToContextState,
23
+ S as createApiError,
24
+ L as createOperationError,
25
+ D as isApiResultError,
26
+ U as isApiResultOperationError,
27
+ P as isApiResultSuccess,
28
+ b as isAuthError,
29
+ w as isAuthLoading,
30
+ y as isAuthenticated,
31
+ z as isClientCtxInitialized,
32
+ M as isClientCtxInitializing,
33
+ W as isClientCtxNotInitialized,
34
+ v as isClientCtxReady,
35
+ X as isClientReady,
36
+ g as isDirectState,
37
+ j as isExtensionState,
38
+ q as isOperationError,
39
+ G as isOverallReady,
40
+ Z as isWebUIClient,
41
+ $ as useBodhi
473
42
  };