@bodhiapp/bodhi-js-react-core 0.0.11 → 0.0.12
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.
|
@@ -31,5 +31,5 @@ export interface BodhiContext {
|
|
|
31
31
|
isDirect: boolean;
|
|
32
32
|
}
|
|
33
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;
|
|
34
|
+
export declare function BodhiProvider({ children, client, modalHtmlPath, handleCallback, callbackPath: userCallbackPath, basePath, logLevel, }: BodhiProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
35
35
|
export declare function useBodhi(): BodhiContext;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
2
|
-
`,JSON.stringify(n,null,2)),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const z=require("react/jsx-runtime"),s=require("@bodhiapp/bodhi-js-core"),r=require("react"),O={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 V({client:e,modalHtmlPath:o,hideSetup:L,onSetupReady:_,setupState:M,basePath:p="/",logLevel:A="warn"}){const x=M!=="ready",v=r.useMemo(()=>new s.Logger("SetupModalProcessor",A),[A]),i=r.useRef(null),l=r.useMemo(()=>new s.BodhiClientUserPrefsManager(s.createStoragePrefixWithBasePath(p,"bodhijs:")),[p]),E=r.useRef(null),S=r.useCallback(t=>t==="direct"?"lna":t==="extension"?"extension":null,[]),R=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"}}}},[]),m=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 a=t.server.status;if(a==="ready"||a==="setup"||a==="resource-admin")return!0}if(n.server.status!=="not-connected"){const a=n.server.status;if(a==="ready"||a==="setup"||a==="resource-admin")return!0}return!1},[]),y=r.useCallback((t,n,a)=>{if(n==="skipped")return{status:"skipped",serverUrl:a};if(t.server.status!=="not-connected"){const u=t.server;return u.status==="ready"||u.status==="setup"||u.status==="resource-admin"?{status:"granted",serverUrl:a}:{status:"unreachable",serverUrl:a,error:{message:u.error?.message||"Server unreachable",code:"lna-unreachable"}}}return n==="granted"?{status:"granted",serverUrl:a}:{status:"prompt",serverUrl:a}},[]),g=r.useCallback(async(t=!1)=>{const n=s.detectBrowser().type,a=s.detectOS().type;let u=await e.getExtensionState();(u.extension==="not-initialized"||t)&&(u=await e.testExtensionConnectivity());let d=await e.getDirectState();const h=l.getDirectStatus();h==="granted"&&(d.server.status==="not-connected"||t)&&(d=await e.testDirectConnectivity());const f=s.getServerUrl(d)||"http://localhost:1135",w=y(d,h,f);return e.getConnectionMode()===null&&(s.isDirectServerReady(d)?await e.setConnectionMode("direct"):s.isExtensionServerReady(u)&&await e.setConnectionMode("extension")),l.isServerInstallConfirmed()||I(u,d)&&l.setServerInstallConfirmed(!0),{extension:R(u),server:b(u),lna:w,lnaServer:m(d),env:{browser:n,os:a},browsers:s.BROWSER_CONFIGS,os:s.OS_CONFIGS,userConfirmations:{serverInstall:l.isServerInstallConfirmed()},selectedConnection:S(e.getConnectionMode())}},[e,l,R,b,m,S,y,I]),C=r.useCallback(()=>{if(!E.current)throw new Error("Cannot get state: currentStateRef is null");return{...E.current,userConfirmations:{serverInstall:l.isServerInstallConfirmed()},selectedConnection:S(e.getConnectionMode())}},[l,e,S]),T=r.useMemo(()=>({[O.MODAL_READY]:async()=>(v.info("MODAL_READY: building initial state"),{setupState:C()}),[O.MODAL_REFRESH]:async()=>{v.info("MODAL_REFRESH: refreshing state");const t=await g(!0);E.current=t;const n=C();return v.info(`MODAL_REFRESH: state refreshed
|
|
2
|
+
`,JSON.stringify(n,null,2)),i.current?.updateState(C()),{setupState:n}},[O.MODAL_LNA_CONNECT]:async t=>{const n=t.payload.serverUrl;console.log("[SetupModalProcessor] LNA connect:",n);const a=await e.testDirectConnectivity(n);if(a.server.status!=="not-connected"){const d=a.server.status;if(d==="ready"||d==="setup"||d==="resource-admin"){l.setDirectStatus("granted"),e.getConnectionMode()===null&&await e.setConnectionMode("direct");const h=await g();return E.current=h,i.current?.updateState(C()),{success:!0}}}const u=await g();return E.current=u,i.current?.updateState(C()),{success:!1}},[O.MODAL_LNA_SKIP]:async()=>{l.setDirectStatus("skipped");const t=await g();return E.current=t,i.current?.updateState(C()),{success:!0}},[O.MODAL_CLOSE]:()=>{L()},[O.MODAL_COMPLETE]:()=>{L()},[O.MODAL_CONFIRM_SERVER_INSTALL]:t=>(l.setServerInstallConfirmed(t.payload.confirmed),i.current?.updateState(C()),{success:!0}),[O.MODAL_SELECT_CONNECTION]:async t=>{const a=t.payload.connection==="lna"?"direct":"extension";return await e.setConnectionMode(a),i.current?.updateState(C()),{success:!0}}}),[v,e,l,g,C,m,L]);return r.useEffect(()=>(i.current=new s.OnboardingModal({modalHtmlPath:o,handlers:T}),()=>{i.current?.destroy(),i.current=null}),[o,T]),r.useEffect(()=>{x&&i.current?g(!0).then(t=>{E.current=t,i.current?.show(t),_?.()}).catch(t=>{console.error("[SetupModalProcessor] buildSetupState failed:",t)}):!x&&i.current&&i.current.destroy()},[x,g,_]),null}const B={status:"not-initialized",mode:null,extensionId:null,url:null,server:s.BACKEND_SERVER_NOT_CONNECTED,error:null},j={status:"initializing",mode:null,extensionId:null,url:null,server:s.BACKEND_SERVER_NOT_CONNECTED,error:null};function U(e){return e.status==="not-initialized"}function F(e){return e.status==="initializing"}function G(e){return e.status!=="not-initialized"&&e.status!=="initializing"}function k(e){return e.status==="ready"}function H(e){return k(e)&&e.server.status==="ready"}function K(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 W={isNotInitialized:U,isInitializing:F,isInitialized:G,isReady:k,isOverallReady:H},N=r.createContext(null);N.displayName="BodhiContext";function q({children:e,client:o,modalHtmlPath:L,handleCallback:_=!0,callbackPath:M,basePath:p="/",logLevel:A="warn"}){const x=p==="/"?"":p.replace(/\/$/,""),v=M??`${x}/callback`,i=r.useMemo(()=>new s.Logger("BodhiProvider",A),[A]),l=r.useRef(!1),E=r.useRef(!1),[S,R]=r.useState(B),[b,m]=r.useState(s.INITIAL_AUTH_STATE),[I,y]=r.useState(!1),[g,C]=r.useState("ready");r.useEffect(()=>{const c=f=>{switch(f.type){case"client-state":R(K(f.state));break;case"auth-state":m(f.state),y(!1);break}};return o.setStateCallback(c),()=>{o.setStateCallback(s.NOOP_STATE_CALLBACK)}},[o]);const T=r.useCallback(async()=>{C("loading")},[]),t=r.useCallback(()=>{C("ready")},[]),n=r.useCallback(()=>{C("loaded")},[]),a=r.useCallback(async c=>{R(j);try{await o.init(c||{})}catch(f){i.error("Init failed:",f)}},[o,i]);r.useEffect(()=>{if(E.current)return;E.current=!0,(async()=>{if(await a(),!_)return;const f=new URL(window.location.href);if(f.pathname!==v)return;const w=f.searchParams.get("code"),P=f.searchParams.get("state");!w||!P||l.current||(l.current=!0,s.isWebUIClient(o)&&(y(!0),o.handleOAuthCallback(w,P).then(()=>{window.history.replaceState({},"",p)}).catch(D=>{i.error("OAuth callback failed:",D),m({status:"error",user:null,accessToken:null,error:{message:D instanceof Error?D.message:"OAuth callback failed",code:"OAUTH_CALLBACK_FAILED"}}),y(!1),window.history.replaceState({},"",p)})))})()},[a,o,_,v,p]);const u=r.useCallback(async()=>{y(!0);try{await o.login()}catch(c){m({status:"error",user:null,accessToken:null,error:{message:c instanceof Error?c.message:"Login failed",code:"LOGIN_FAILED"}}),y(!1)}},[o]),d=r.useCallback(async()=>{try{await o.logout()}catch(c){m({status:"error",user:null,accessToken:null,error:{message:c instanceof Error?c.message:"Logout failed",code:"LOGOUT_FAILED"}})}},[o]),h=r.useMemo(()=>{const c=S.status==="ready",f=S.server.status==="ready";return{client:o,clientState:S,auth:b,isAuthLoading:I,login:u,logout:d,showSetup:T,hideSetup:t,setupState:g,isAuthenticated:b.status==="authenticated",canLogin:c&&!I,isReady:c,isServerReady:f,isOverallReady:c&&f,isInitializing:S.status==="initializing",isExtension:S.mode==="extension",isDirect:S.mode==="direct"}},[o,S,b,I,g,u,d,T,t]);return z.jsxs(N.Provider,{value:h,children:[z.jsx(V,{client:o,modalHtmlPath:L,hideSetup:t,onSetupReady:n,setupState:g,basePath:p,logLevel:A}),e]})}function X(){const e=r.useContext(N);if(!e)throw new Error("useBodhi must be used within BodhiProvider");return e}const Y="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=q;exports.BodhiReactContext=N;exports.ClientCtxState=W;exports.INITIALIZING_CLIENT_CONTEXT_STATE=j;exports.INITIAL_CLIENT_CONTEXT_STATE=B;exports.REACT_CORE_BUILD_MODE=Y;exports.clientStateToContextState=K;exports.isClientCtxInitialized=G;exports.isClientCtxInitializing=F;exports.isClientCtxNotInitialized=U;exports.isClientCtxReady=k;exports.isOverallReady=H;exports.useBodhi=X;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { jsxs as
|
|
2
|
-
import { Logger as
|
|
3
|
-
import { createApiError as
|
|
4
|
-
import { useMemo as
|
|
5
|
-
const
|
|
1
|
+
import { jsxs as G, jsx as K } from "react/jsx-runtime";
|
|
2
|
+
import { Logger as U, BodhiClientUserPrefsManager as V, createStoragePrefixWithBasePath as W, detectBrowser as j, detectOS as Y, getServerUrl as q, isDirectServerReady as X, isExtensionServerReady as $, OS_CONFIGS as J, BROWSER_CONFIGS as Z, OnboardingModal as Q, BACKEND_SERVER_NOT_CONNECTED as F, isExtensionState as ee, INITIAL_AUTH_STATE as te, NOOP_STATE_CALLBACK as re, isWebUIClient as ne } from "@bodhiapp/bodhi-js-core";
|
|
3
|
+
import { createApiError as he, createOperationError as Le, isApiResultError as we, isApiResultOperationError as xe, isApiResultSuccess as Ie, isAuthError as _e, isAuthLoading as Re, isAuthenticated as De, isClientReady as Me, isDirectState as Ne, isExtensionState as Te, isOperationError as ke, isWebUIClient as be } from "@bodhiapp/bodhi-js-core";
|
|
4
|
+
import { useMemo as D, useRef as T, useCallback as l, useEffect as k, createContext as se, useState as N, useContext as oe } from "react";
|
|
5
|
+
const E = {
|
|
6
6
|
// Modal lifecycle
|
|
7
7
|
MODAL_READY: "modal:ready",
|
|
8
8
|
MODAL_REFRESH: "modal:refresh",
|
|
@@ -16,22 +16,22 @@ const m = {
|
|
|
16
16
|
// Connection selection
|
|
17
17
|
MODAL_SELECT_CONNECTION: "modal:select-connection"
|
|
18
18
|
};
|
|
19
|
-
function
|
|
19
|
+
function ae({
|
|
20
20
|
client: e,
|
|
21
|
-
modalHtmlPath:
|
|
21
|
+
modalHtmlPath: s,
|
|
22
22
|
hideSetup: w,
|
|
23
23
|
onSetupReady: x,
|
|
24
|
-
setupState:
|
|
25
|
-
basePath:
|
|
24
|
+
setupState: b,
|
|
25
|
+
basePath: m = "/",
|
|
26
26
|
logLevel: A = "warn"
|
|
27
27
|
}) {
|
|
28
|
-
const
|
|
29
|
-
() => new
|
|
30
|
-
[
|
|
31
|
-
),
|
|
28
|
+
const I = b !== "ready", y = D(() => new U("SetupModalProcessor", A), [A]), o = T(null), u = D(
|
|
29
|
+
() => new V(W(m, "bodhijs:")),
|
|
30
|
+
[m]
|
|
31
|
+
), v = T(null), S = l(
|
|
32
32
|
(t) => t === "direct" ? "lna" : t === "extension" ? "extension" : null,
|
|
33
33
|
[]
|
|
34
|
-
),
|
|
34
|
+
), _ = l((t) => t.extension === "ready" ? {
|
|
35
35
|
status: "ready",
|
|
36
36
|
version: "unknown",
|
|
37
37
|
// TODO: have ExtensionState also get extension version
|
|
@@ -42,7 +42,7 @@ function se({
|
|
|
42
42
|
} : {
|
|
43
43
|
status: "unreachable",
|
|
44
44
|
error: { message: "Client not initialized", code: "ext-connection-failed" }
|
|
45
|
-
}, []), O =
|
|
45
|
+
}, []), O = l((t) => {
|
|
46
46
|
if (t.server.status === "pending-extension-ready")
|
|
47
47
|
return {
|
|
48
48
|
status: "pending-extension-ready",
|
|
@@ -95,7 +95,7 @@ function se({
|
|
|
95
95
|
}
|
|
96
96
|
};
|
|
97
97
|
}
|
|
98
|
-
}, []),
|
|
98
|
+
}, []), p = l((t) => {
|
|
99
99
|
if (t.server.status === "not-connected")
|
|
100
100
|
return { status: "pending-lna-ready" };
|
|
101
101
|
const r = t.server;
|
|
@@ -118,169 +118,169 @@ function se({
|
|
|
118
118
|
error: { message: "Unknown server status" }
|
|
119
119
|
};
|
|
120
120
|
}
|
|
121
|
-
}, []),
|
|
121
|
+
}, []), h = l(
|
|
122
122
|
(t, r) => {
|
|
123
123
|
if (t.server.status !== "pending-extension-ready") {
|
|
124
|
-
const
|
|
125
|
-
if (
|
|
124
|
+
const n = t.server.status;
|
|
125
|
+
if (n === "ready" || n === "setup" || n === "resource-admin")
|
|
126
126
|
return !0;
|
|
127
127
|
}
|
|
128
128
|
if (r.server.status !== "not-connected") {
|
|
129
|
-
const
|
|
130
|
-
if (
|
|
129
|
+
const n = r.server.status;
|
|
130
|
+
if (n === "ready" || n === "setup" || n === "resource-admin")
|
|
131
131
|
return !0;
|
|
132
132
|
}
|
|
133
133
|
return !1;
|
|
134
134
|
},
|
|
135
135
|
[]
|
|
136
|
-
),
|
|
137
|
-
(t, r,
|
|
136
|
+
), g = l(
|
|
137
|
+
(t, r, n) => {
|
|
138
138
|
if (r === "skipped")
|
|
139
|
-
return { status: "skipped", serverUrl:
|
|
139
|
+
return { status: "skipped", serverUrl: n };
|
|
140
140
|
if (t.server.status !== "not-connected") {
|
|
141
|
-
const
|
|
142
|
-
return
|
|
141
|
+
const a = t.server;
|
|
142
|
+
return a.status === "ready" || a.status === "setup" || a.status === "resource-admin" ? { status: "granted", serverUrl: n } : {
|
|
143
143
|
status: "unreachable",
|
|
144
|
-
serverUrl:
|
|
144
|
+
serverUrl: n,
|
|
145
145
|
error: {
|
|
146
|
-
message:
|
|
146
|
+
message: a.error?.message || "Server unreachable",
|
|
147
147
|
code: "lna-unreachable"
|
|
148
148
|
}
|
|
149
149
|
};
|
|
150
150
|
}
|
|
151
|
-
return r === "granted" ? { status: "granted", serverUrl:
|
|
151
|
+
return r === "granted" ? { status: "granted", serverUrl: n } : { status: "prompt", serverUrl: n };
|
|
152
152
|
},
|
|
153
153
|
[]
|
|
154
|
-
),
|
|
154
|
+
), C = l(
|
|
155
155
|
async (t = !1) => {
|
|
156
|
-
const r =
|
|
157
|
-
let
|
|
158
|
-
(
|
|
159
|
-
let
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
const
|
|
163
|
-
return e.getConnectionMode() === null && (
|
|
164
|
-
extension:
|
|
165
|
-
server: O(
|
|
166
|
-
lna:
|
|
167
|
-
lnaServer:
|
|
168
|
-
env: { browser: r, os:
|
|
169
|
-
browsers:
|
|
170
|
-
os:
|
|
171
|
-
userConfirmations: { serverInstall:
|
|
172
|
-
selectedConnection:
|
|
156
|
+
const r = j().type, n = Y().type;
|
|
157
|
+
let a = await e.getExtensionState();
|
|
158
|
+
(a.extension === "not-initialized" || t) && (a = await e.testExtensionConnectivity());
|
|
159
|
+
let c = await e.getDirectState();
|
|
160
|
+
const L = u.getDirectStatus();
|
|
161
|
+
L === "granted" && (c.server.status === "not-connected" || t) && (c = await e.testDirectConnectivity());
|
|
162
|
+
const d = q(c) || "http://localhost:1135", M = g(c, L, d);
|
|
163
|
+
return e.getConnectionMode() === null && (X(c) ? await e.setConnectionMode("direct") : $(a) && await e.setConnectionMode("extension")), u.isServerInstallConfirmed() || h(a, c) && u.setServerInstallConfirmed(!0), {
|
|
164
|
+
extension: _(a),
|
|
165
|
+
server: O(a),
|
|
166
|
+
lna: M,
|
|
167
|
+
lnaServer: p(c),
|
|
168
|
+
env: { browser: r, os: n },
|
|
169
|
+
browsers: Z,
|
|
170
|
+
os: J,
|
|
171
|
+
userConfirmations: { serverInstall: u.isServerInstallConfirmed() },
|
|
172
|
+
selectedConnection: S(e.getConnectionMode())
|
|
173
173
|
};
|
|
174
174
|
},
|
|
175
175
|
[
|
|
176
176
|
e,
|
|
177
|
-
|
|
178
|
-
|
|
177
|
+
u,
|
|
178
|
+
_,
|
|
179
179
|
O,
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
180
|
+
p,
|
|
181
|
+
S,
|
|
182
|
+
g,
|
|
183
|
+
h
|
|
184
184
|
]
|
|
185
|
-
),
|
|
186
|
-
if (!
|
|
185
|
+
), f = l(() => {
|
|
186
|
+
if (!v.current)
|
|
187
187
|
throw new Error("Cannot get state: currentStateRef is null");
|
|
188
188
|
return {
|
|
189
|
-
...
|
|
189
|
+
...v.current,
|
|
190
190
|
// Override userConfirmations from storage (in case updated outside buildSetupState)
|
|
191
191
|
userConfirmations: {
|
|
192
|
-
serverInstall:
|
|
192
|
+
serverInstall: u.isServerInstallConfirmed()
|
|
193
193
|
},
|
|
194
194
|
// Override selectedConnection from client (in case changed via handler)
|
|
195
|
-
selectedConnection:
|
|
195
|
+
selectedConnection: S(e.getConnectionMode())
|
|
196
196
|
};
|
|
197
|
-
}, [
|
|
197
|
+
}, [u, e, S]), R = D(
|
|
198
198
|
() => ({
|
|
199
|
-
[
|
|
200
|
-
[
|
|
201
|
-
|
|
202
|
-
const t = await
|
|
203
|
-
|
|
204
|
-
const r =
|
|
205
|
-
return
|
|
206
|
-
`, JSON.stringify(r, null, 2)),
|
|
199
|
+
[E.MODAL_READY]: async () => (y.info("MODAL_READY: building initial state"), { setupState: f() }),
|
|
200
|
+
[E.MODAL_REFRESH]: async () => {
|
|
201
|
+
y.info("MODAL_REFRESH: refreshing state");
|
|
202
|
+
const t = await C(!0);
|
|
203
|
+
v.current = t;
|
|
204
|
+
const r = f();
|
|
205
|
+
return y.info(`MODAL_REFRESH: state refreshed
|
|
206
|
+
`, JSON.stringify(r, null, 2)), o.current?.updateState(f()), { setupState: r };
|
|
207
207
|
},
|
|
208
|
-
[
|
|
208
|
+
[E.MODAL_LNA_CONNECT]: async (t) => {
|
|
209
209
|
const r = t.payload.serverUrl;
|
|
210
210
|
console.log("[SetupModalProcessor] LNA connect:", r);
|
|
211
|
-
const
|
|
212
|
-
if (
|
|
213
|
-
const
|
|
214
|
-
if (
|
|
215
|
-
|
|
216
|
-
const
|
|
217
|
-
return
|
|
211
|
+
const n = await e.testDirectConnectivity(r);
|
|
212
|
+
if (n.server.status !== "not-connected") {
|
|
213
|
+
const c = n.server.status;
|
|
214
|
+
if (c === "ready" || c === "setup" || c === "resource-admin") {
|
|
215
|
+
u.setDirectStatus("granted"), e.getConnectionMode() === null && await e.setConnectionMode("direct");
|
|
216
|
+
const L = await C();
|
|
217
|
+
return v.current = L, o.current?.updateState(f()), { success: !0 };
|
|
218
218
|
}
|
|
219
219
|
}
|
|
220
|
-
const
|
|
221
|
-
return
|
|
220
|
+
const a = await C();
|
|
221
|
+
return v.current = a, o.current?.updateState(f()), { success: !1 };
|
|
222
222
|
},
|
|
223
|
-
[
|
|
224
|
-
|
|
225
|
-
const t = await
|
|
226
|
-
return
|
|
223
|
+
[E.MODAL_LNA_SKIP]: async () => {
|
|
224
|
+
u.setDirectStatus("skipped");
|
|
225
|
+
const t = await C();
|
|
226
|
+
return v.current = t, o.current?.updateState(f()), { success: !0 };
|
|
227
227
|
},
|
|
228
|
-
[
|
|
228
|
+
[E.MODAL_CLOSE]: () => {
|
|
229
229
|
w();
|
|
230
230
|
},
|
|
231
|
-
[
|
|
231
|
+
[E.MODAL_COMPLETE]: () => {
|
|
232
232
|
w();
|
|
233
233
|
},
|
|
234
|
-
[
|
|
235
|
-
[
|
|
236
|
-
const
|
|
237
|
-
return await e.setConnectionMode(
|
|
234
|
+
[E.MODAL_CONFIRM_SERVER_INSTALL]: (t) => (u.setServerInstallConfirmed(t.payload.confirmed), o.current?.updateState(f()), { success: !0 }),
|
|
235
|
+
[E.MODAL_SELECT_CONNECTION]: async (t) => {
|
|
236
|
+
const n = t.payload.connection === "lna" ? "direct" : "extension";
|
|
237
|
+
return await e.setConnectionMode(n), o.current?.updateState(f()), { success: !0 };
|
|
238
238
|
}
|
|
239
239
|
}),
|
|
240
|
-
[
|
|
240
|
+
[y, e, u, C, f, p, w]
|
|
241
241
|
);
|
|
242
|
-
return
|
|
243
|
-
|
|
244
|
-
}), [
|
|
245
|
-
|
|
246
|
-
|
|
242
|
+
return k(() => (o.current = new Q({ modalHtmlPath: s, handlers: R }), () => {
|
|
243
|
+
o.current?.destroy(), o.current = null;
|
|
244
|
+
}), [s, R]), k(() => {
|
|
245
|
+
I && o.current ? C(!0).then((t) => {
|
|
246
|
+
v.current = t, o.current?.show(t), x?.();
|
|
247
247
|
}).catch((t) => {
|
|
248
248
|
console.error("[SetupModalProcessor] buildSetupState failed:", t);
|
|
249
|
-
}) : !
|
|
250
|
-
}, [
|
|
249
|
+
}) : !I && o.current && o.current.destroy();
|
|
250
|
+
}, [I, C, x]), null;
|
|
251
251
|
}
|
|
252
|
-
const
|
|
252
|
+
const ie = {
|
|
253
253
|
status: "not-initialized",
|
|
254
254
|
mode: null,
|
|
255
255
|
extensionId: null,
|
|
256
256
|
url: null,
|
|
257
|
-
server:
|
|
257
|
+
server: F,
|
|
258
258
|
error: null
|
|
259
|
-
},
|
|
259
|
+
}, ue = {
|
|
260
260
|
status: "initializing",
|
|
261
261
|
mode: null,
|
|
262
262
|
extensionId: null,
|
|
263
263
|
url: null,
|
|
264
|
-
server:
|
|
264
|
+
server: F,
|
|
265
265
|
error: null
|
|
266
266
|
};
|
|
267
|
-
function
|
|
267
|
+
function ce(e) {
|
|
268
268
|
return e.status === "not-initialized";
|
|
269
269
|
}
|
|
270
|
-
function
|
|
270
|
+
function de(e) {
|
|
271
271
|
return e.status === "initializing";
|
|
272
272
|
}
|
|
273
|
-
function
|
|
273
|
+
function le(e) {
|
|
274
274
|
return e.status !== "not-initialized" && e.status !== "initializing";
|
|
275
275
|
}
|
|
276
|
-
function
|
|
276
|
+
function H(e) {
|
|
277
277
|
return e.status === "ready";
|
|
278
278
|
}
|
|
279
|
-
function
|
|
280
|
-
return
|
|
279
|
+
function fe(e) {
|
|
280
|
+
return H(e) && e.server.status === "ready";
|
|
281
281
|
}
|
|
282
|
-
function
|
|
283
|
-
return
|
|
282
|
+
function Se(e) {
|
|
283
|
+
return ee(e) ? {
|
|
284
284
|
status: e.extension === "not-initialized" ? "initializing" : e.extension === "not-found" ? "extension-not-found" : "ready",
|
|
285
285
|
mode: "extension",
|
|
286
286
|
extensionId: e.extensionId,
|
|
@@ -296,178 +296,178 @@ function le(e) {
|
|
|
296
296
|
error: e.server.error
|
|
297
297
|
};
|
|
298
298
|
}
|
|
299
|
-
const
|
|
300
|
-
isNotInitialized:
|
|
301
|
-
isInitializing:
|
|
302
|
-
isInitialized:
|
|
303
|
-
isReady:
|
|
304
|
-
isOverallReady:
|
|
305
|
-
},
|
|
306
|
-
|
|
307
|
-
function
|
|
299
|
+
const pe = {
|
|
300
|
+
isNotInitialized: ce,
|
|
301
|
+
isInitializing: de,
|
|
302
|
+
isInitialized: le,
|
|
303
|
+
isReady: H,
|
|
304
|
+
isOverallReady: fe
|
|
305
|
+
}, B = se(null);
|
|
306
|
+
B.displayName = "BodhiContext";
|
|
307
|
+
function ge({
|
|
308
308
|
children: e,
|
|
309
|
-
client:
|
|
309
|
+
client: s,
|
|
310
310
|
modalHtmlPath: w,
|
|
311
311
|
handleCallback: x = !0,
|
|
312
|
-
callbackPath:
|
|
313
|
-
basePath:
|
|
312
|
+
callbackPath: b,
|
|
313
|
+
basePath: m = "/",
|
|
314
314
|
logLevel: A = "warn"
|
|
315
315
|
}) {
|
|
316
|
-
const
|
|
317
|
-
|
|
318
|
-
const
|
|
319
|
-
switch (
|
|
316
|
+
const I = m === "/" ? "" : m.replace(/\/$/, ""), y = b ?? `${I}/callback`, o = D(() => new U("BodhiProvider", A), [A]), u = T(!1), v = T(!1), [S, _] = N(ie), [O, p] = N(te), [h, g] = N(!1), [C, f] = N("ready");
|
|
317
|
+
k(() => {
|
|
318
|
+
const i = (d) => {
|
|
319
|
+
switch (d.type) {
|
|
320
320
|
case "client-state":
|
|
321
|
-
|
|
321
|
+
_(Se(d.state));
|
|
322
322
|
break;
|
|
323
323
|
case "auth-state":
|
|
324
|
-
|
|
324
|
+
p(d.state), g(!1);
|
|
325
325
|
break;
|
|
326
326
|
}
|
|
327
327
|
};
|
|
328
|
-
return
|
|
329
|
-
|
|
328
|
+
return s.setStateCallback(i), () => {
|
|
329
|
+
s.setStateCallback(re);
|
|
330
330
|
};
|
|
331
|
-
}, [
|
|
332
|
-
const
|
|
333
|
-
|
|
334
|
-
}, []),
|
|
335
|
-
|
|
336
|
-
}, []),
|
|
337
|
-
|
|
338
|
-
}, []),
|
|
339
|
-
async (
|
|
340
|
-
|
|
331
|
+
}, [s]);
|
|
332
|
+
const R = l(async () => {
|
|
333
|
+
f("loading");
|
|
334
|
+
}, []), t = l(() => {
|
|
335
|
+
f("ready");
|
|
336
|
+
}, []), r = l(() => {
|
|
337
|
+
f("loaded");
|
|
338
|
+
}, []), n = l(
|
|
339
|
+
async (i) => {
|
|
340
|
+
_(ue);
|
|
341
341
|
try {
|
|
342
|
-
await
|
|
343
|
-
} catch (
|
|
344
|
-
|
|
342
|
+
await s.init(i || {});
|
|
343
|
+
} catch (d) {
|
|
344
|
+
o.error("Init failed:", d);
|
|
345
345
|
}
|
|
346
346
|
},
|
|
347
|
-
[
|
|
347
|
+
[s, o]
|
|
348
348
|
);
|
|
349
|
-
|
|
350
|
-
if (
|
|
351
|
-
|
|
352
|
-
if (await
|
|
353
|
-
const
|
|
354
|
-
if (
|
|
355
|
-
const
|
|
356
|
-
!
|
|
357
|
-
window.history.replaceState({}, "",
|
|
358
|
-
}).catch((
|
|
359
|
-
|
|
349
|
+
k(() => {
|
|
350
|
+
if (v.current) return;
|
|
351
|
+
v.current = !0, (async () => {
|
|
352
|
+
if (await n(), !x) return;
|
|
353
|
+
const d = new URL(window.location.href);
|
|
354
|
+
if (d.pathname !== y) return;
|
|
355
|
+
const M = d.searchParams.get("code"), P = d.searchParams.get("state");
|
|
356
|
+
!M || !P || u.current || (u.current = !0, ne(s) && (g(!0), s.handleOAuthCallback(M, P).then(() => {
|
|
357
|
+
window.history.replaceState({}, "", m);
|
|
358
|
+
}).catch((z) => {
|
|
359
|
+
o.error("OAuth callback failed:", z), p({
|
|
360
360
|
status: "error",
|
|
361
361
|
user: null,
|
|
362
362
|
accessToken: null,
|
|
363
363
|
error: {
|
|
364
|
-
message:
|
|
364
|
+
message: z instanceof Error ? z.message : "OAuth callback failed",
|
|
365
365
|
code: "OAUTH_CALLBACK_FAILED"
|
|
366
366
|
}
|
|
367
|
-
}),
|
|
367
|
+
}), g(!1), window.history.replaceState({}, "", m);
|
|
368
368
|
})));
|
|
369
369
|
})();
|
|
370
|
-
}, [
|
|
371
|
-
const
|
|
372
|
-
|
|
370
|
+
}, [n, s, x, y, m]);
|
|
371
|
+
const a = l(async () => {
|
|
372
|
+
g(!0);
|
|
373
373
|
try {
|
|
374
|
-
await
|
|
375
|
-
} catch (
|
|
376
|
-
|
|
374
|
+
await s.login();
|
|
375
|
+
} catch (i) {
|
|
376
|
+
p({
|
|
377
377
|
status: "error",
|
|
378
378
|
user: null,
|
|
379
379
|
accessToken: null,
|
|
380
380
|
error: {
|
|
381
|
-
message:
|
|
381
|
+
message: i instanceof Error ? i.message : "Login failed",
|
|
382
382
|
code: "LOGIN_FAILED"
|
|
383
383
|
}
|
|
384
|
-
}),
|
|
384
|
+
}), g(!1);
|
|
385
385
|
}
|
|
386
|
-
}, [
|
|
386
|
+
}, [s]), c = l(async () => {
|
|
387
387
|
try {
|
|
388
|
-
await
|
|
389
|
-
} catch (
|
|
390
|
-
|
|
388
|
+
await s.logout();
|
|
389
|
+
} catch (i) {
|
|
390
|
+
p({
|
|
391
391
|
status: "error",
|
|
392
392
|
user: null,
|
|
393
393
|
accessToken: null,
|
|
394
394
|
error: {
|
|
395
|
-
message:
|
|
395
|
+
message: i instanceof Error ? i.message : "Logout failed",
|
|
396
396
|
code: "LOGOUT_FAILED"
|
|
397
397
|
}
|
|
398
398
|
});
|
|
399
399
|
}
|
|
400
|
-
}, [
|
|
401
|
-
const
|
|
400
|
+
}, [s]), L = D(() => {
|
|
401
|
+
const i = S.status === "ready", d = S.server.status === "ready";
|
|
402
402
|
return {
|
|
403
|
-
client:
|
|
404
|
-
clientState:
|
|
405
|
-
auth:
|
|
406
|
-
isAuthLoading:
|
|
407
|
-
login:
|
|
408
|
-
logout:
|
|
409
|
-
showSetup:
|
|
410
|
-
hideSetup:
|
|
411
|
-
setupState:
|
|
403
|
+
client: s,
|
|
404
|
+
clientState: S,
|
|
405
|
+
auth: O,
|
|
406
|
+
isAuthLoading: h,
|
|
407
|
+
login: a,
|
|
408
|
+
logout: c,
|
|
409
|
+
showSetup: R,
|
|
410
|
+
hideSetup: t,
|
|
411
|
+
setupState: C,
|
|
412
412
|
// Computed auth properties
|
|
413
|
-
isAuthenticated:
|
|
414
|
-
canLogin:
|
|
413
|
+
isAuthenticated: O.status === "authenticated",
|
|
414
|
+
canLogin: i && !h,
|
|
415
415
|
// Computed connection properties
|
|
416
|
-
isReady:
|
|
417
|
-
isServerReady:
|
|
418
|
-
isOverallReady:
|
|
419
|
-
isInitializing:
|
|
420
|
-
isExtension:
|
|
421
|
-
isDirect:
|
|
416
|
+
isReady: i,
|
|
417
|
+
isServerReady: d,
|
|
418
|
+
isOverallReady: i && d,
|
|
419
|
+
isInitializing: S.status === "initializing",
|
|
420
|
+
isExtension: S.mode === "extension",
|
|
421
|
+
isDirect: S.mode === "direct"
|
|
422
422
|
};
|
|
423
|
-
}, [
|
|
424
|
-
return /* @__PURE__ */
|
|
425
|
-
/* @__PURE__ */
|
|
426
|
-
|
|
423
|
+
}, [s, S, O, h, C, a, c, R, t]);
|
|
424
|
+
return /* @__PURE__ */ G(B.Provider, { value: L, children: [
|
|
425
|
+
/* @__PURE__ */ K(
|
|
426
|
+
ae,
|
|
427
427
|
{
|
|
428
|
-
client:
|
|
428
|
+
client: s,
|
|
429
429
|
modalHtmlPath: w,
|
|
430
|
-
hideSetup:
|
|
431
|
-
onSetupReady:
|
|
432
|
-
setupState:
|
|
433
|
-
basePath:
|
|
430
|
+
hideSetup: t,
|
|
431
|
+
onSetupReady: r,
|
|
432
|
+
setupState: C,
|
|
433
|
+
basePath: m,
|
|
434
434
|
logLevel: A
|
|
435
435
|
}
|
|
436
436
|
),
|
|
437
437
|
e
|
|
438
438
|
] });
|
|
439
439
|
}
|
|
440
|
-
function
|
|
441
|
-
const e =
|
|
440
|
+
function Ee() {
|
|
441
|
+
const e = oe(B);
|
|
442
442
|
if (!e) throw new Error("useBodhi must be used within BodhiProvider");
|
|
443
443
|
return e;
|
|
444
444
|
}
|
|
445
|
-
const
|
|
445
|
+
const ye = "production";
|
|
446
446
|
export {
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
447
|
+
ge as BodhiProvider,
|
|
448
|
+
B as BodhiReactContext,
|
|
449
|
+
pe as ClientCtxState,
|
|
450
|
+
ue as INITIALIZING_CLIENT_CONTEXT_STATE,
|
|
451
|
+
ie as INITIAL_CLIENT_CONTEXT_STATE,
|
|
452
|
+
ye as REACT_CORE_BUILD_MODE,
|
|
453
|
+
Se as clientStateToContextState,
|
|
454
|
+
he as createApiError,
|
|
455
|
+
Le as createOperationError,
|
|
456
|
+
we as isApiResultError,
|
|
457
|
+
xe as isApiResultOperationError,
|
|
458
|
+
Ie as isApiResultSuccess,
|
|
459
|
+
_e as isAuthError,
|
|
460
|
+
Re as isAuthLoading,
|
|
461
|
+
De as isAuthenticated,
|
|
462
|
+
le as isClientCtxInitialized,
|
|
463
|
+
de as isClientCtxInitializing,
|
|
464
|
+
ce as isClientCtxNotInitialized,
|
|
465
|
+
H as isClientCtxReady,
|
|
466
|
+
Me as isClientReady,
|
|
467
|
+
Ne as isDirectState,
|
|
468
|
+
Te as isExtensionState,
|
|
469
|
+
ke as isOperationError,
|
|
470
|
+
fe as isOverallReady,
|
|
471
|
+
be as isWebUIClient,
|
|
472
|
+
Ee as useBodhi
|
|
473
473
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bodhiapp/bodhi-js-react-core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.12",
|
|
4
4
|
"description": "Core React bindings for Bodhi Browser SDK (dependency injection)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/bodhi-react-core.cjs.js",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"typecheck": "tsc --noEmit"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@bodhiapp/bodhi-js-core": "0.0.
|
|
45
|
+
"@bodhiapp/bodhi-js-core": "0.0.12",
|
|
46
46
|
"@bodhiapp/ts-client": "0.1.9"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|