codicent-app-sdk 0.4.29 → 0.5.0

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.
@@ -0,0 +1,81 @@
1
+ import { Dispatch } from "react";
2
+ import { AppInfo, CodicentService } from "../services/codicent";
3
+ import { StateContext } from "../utils/appState";
4
+ export type AppPhase = "authenticating" | "notAuthenticated" | "checkingCodicentAccess" | "registering" | "registered" | "loadingUser" | "checkingPurchase" | "needsPurchase" | "gettingApps" | "creatingApp" | "checkingAccess" | "noAccess" | "hasAccess" | "loggingOut" | "error" | "anonymous" | "restoringFromCache" | "validatingCache";
5
+ export type AppAction = {
6
+ type: "LOGOUT";
7
+ } | {
8
+ type: "NOT_AUTHENTICATED";
9
+ } | {
10
+ type: "AUTHENTICATED";
11
+ accessToken: string;
12
+ user: {
13
+ sub: string;
14
+ email: string;
15
+ };
16
+ } | {
17
+ type: "REGISTERED";
18
+ nickname: string;
19
+ } | {
20
+ type: "NOT_REGISTERED";
21
+ } | {
22
+ type: "REGISTER_AUTO_SUCCESS";
23
+ nickname: string;
24
+ } | {
25
+ type: "REGISTER_AUTO_FAIL";
26
+ error: string;
27
+ errorType?: StateContext["errorType"];
28
+ } | {
29
+ type: "USER_LOADED";
30
+ name: string;
31
+ } | {
32
+ type: "PURCHASE_VALID";
33
+ } | {
34
+ type: "PURCHASE_INVALID";
35
+ } | {
36
+ type: "APPS_LOADED";
37
+ apps: AppInfo[];
38
+ } | {
39
+ type: "APPS_FAILED";
40
+ error: string;
41
+ } | {
42
+ type: "APP_CREATED";
43
+ appId: string;
44
+ } | {
45
+ type: "APP_CREATE_FAILED";
46
+ error: string;
47
+ } | {
48
+ type: "SET_ANONYMOUS";
49
+ } | {
50
+ type: "SET_SELECTED_APP";
51
+ appId: string;
52
+ } | {
53
+ type: "UPDATE_CONTEXT";
54
+ updates: Partial<StateContext>;
55
+ } | {
56
+ type: "CACHE_VALIDATED";
57
+ } | {
58
+ type: "CACHE_VALIDATION_FAILED";
59
+ lenient: boolean;
60
+ };
61
+ export interface AppReducerState {
62
+ phase: AppPhase;
63
+ context: StateContext;
64
+ }
65
+ /** Phases where isBusy() should return true */
66
+ export declare const BUSY_PHASES: AppPhase[];
67
+ export declare const isBusyPhase: (phase: AppPhase) => boolean;
68
+ export declare function appStateReducer(state: AppReducerState, action: AppAction): AppReducerState;
69
+ /**
70
+ * Creates the initial reducer state. Reads the cache synchronously so the
71
+ * very first render is already in the correct phase (no flicker).
72
+ */
73
+ export declare function createInitialState(): AppReducerState;
74
+ /** Persist the current session to localStorage cache. */
75
+ export declare function saveSession(context: StateContext): void;
76
+ /**
77
+ * Runs the three background validation checks (registration, purchase, apps)
78
+ * after restoring from cache. Dispatches CACHE_VALIDATED or CACHE_VALIDATION_FAILED.
79
+ */
80
+ export declare function runBackgroundValidation(service: CodicentService, context: StateContext, dispatch: Dispatch<AppAction>): Promise<void>;
81
+ //# sourceMappingURL=useAppState.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAppState.d.ts","sourceRoot":"","sources":["../../../src/hooks/useAppState.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ "use strict";var e=require("../config/index.js"),t=require("../utils/cacheManager.js");const s=["checkingCodicentAccess","registering","loadingUser","checkingPurchase","gettingApps","creatingApp","checkingAccess","loggingOut"];function a(){const t={isAuthenticated:!1,isRegistered:void 0,hasValidPurchase:void 0,hasAccess:!1,selectedApp:void 0,error:null,errorType:void 0,accessToken:void 0,nickname:void 0,apps:[],hasApps:!1,appsLoaded:!1,user:void 0,name:void 0,isAnonymous:void 0,isFromCache:void 0,needsValidation:void 0};return e.getConfigValue("APP_NAME")?localStorage.removeItem("selectedApp"):t.selectedApp=localStorage.getItem("selectedApp")||void 0,e.getConfigValue("APP_PREFIX")&&t.selectedApp&&!t.selectedApp.startsWith(e.getConfigValue("APP_PREFIX"))&&(t.selectedApp=void 0),t}function n(s){if(!e.getConfigValue("ENABLE_STATE_CACHE"))return;if(!s.nickname||!s.selectedApp)return;const a={nickname:s.nickname,name:s.name||"",selectedApp:s.selectedApp,apps:s.apps||[],hasValidPurchase:s.hasValidPurchase||!1,isRegistered:s.isRegistered||!1,cachedAt:Date.now(),expiresAt:Date.now()+e.getConfigValue("SESSION_CACHE_TTL"),version:"1.0.0"};t.stateMachineCacheManager.set("user_session",a,e.getConfigValue("SESSION_CACHE_TTL")),console.log("AppState: Saved session to cache")}exports.BUSY_PHASES=s,exports.appStateReducer=function(t,s){switch(s.type){case"LOGOUT":return{phase:"loggingOut",context:a()};case"NOT_AUTHENTICATED":return"loggingOut"===t.phase||"anonymous"===t.phase?t:"hasAccess"===t.phase?{phase:"loggingOut",context:a()}:{phase:"notAuthenticated",context:a()};case"AUTHENTICATED":{const{accessToken:e,user:a}=s;return"anonymous"===t.phase?t:"hasAccess"===t.phase&&t.context.isFromCache?{...t,context:{...t.context,accessToken:e,user:a,isAuthenticated:!0}}:"hasAccess"===t.phase?t:{phase:"checkingCodicentAccess",context:{...t.context,isAuthenticated:!0,accessToken:e,user:a}}}case"REGISTERED":case"REGISTER_AUTO_SUCCESS":return localStorage.setItem("nickname",s.nickname),{phase:"loadingUser",context:{...t.context,isRegistered:!0,nickname:s.nickname}};case"NOT_REGISTERED":return{phase:"registering",context:{...t.context,isRegistered:!1}};case"REGISTER_AUTO_FAIL":return{phase:"error",context:{...t.context,error:s.error,errorType:s.errorType}};case"USER_LOADED":return{phase:e.getConfigValue("SUBSCRIPTION_NEEDED")?"checkingPurchase":"gettingApps",context:{...t.context,name:s.name}};case"PURCHASE_VALID":return{phase:"gettingApps",context:{...t.context,hasValidPurchase:!0}};case"PURCHASE_INVALID":return{phase:"needsPurchase",context:{...t.context,hasValidPurchase:!1}};case"APPS_LOADED":{const{apps:a}=s,n=e.getConfigValue("APP_NAME")||void 0,c=e.getConfigValue("APP_PREFIX")||void 0,r=c?a.filter((e=>e.id.startsWith(c))):a;if(0===r.length&&!n)return{phase:"creatingApp",context:{...t.context,apps:r,hasApps:!1,appsLoaded:!0,selectedApp:void 0}};const o=function(e,t,s){return s?e.some((e=>e.id===s))?s:null:t&&e.some((e=>e.id===t))?t:e.length>0?e[0].id:null}(r,t.context.selectedApp,n);return o?{phase:"hasAccess",context:{...t.context,apps:r,hasApps:!0,appsLoaded:!0,selectedApp:o,hasAccess:!0}}:{phase:"noAccess",context:{...t.context,apps:r,hasApps:r.length>0,appsLoaded:!0}}}case"APPS_FAILED":return{phase:"error",context:{...t.context,error:s.error,errorType:"ErrorGettingApps"}};case"APP_CREATED":return{phase:"hasAccess",context:{...t.context,selectedApp:s.appId,apps:[...t.context.apps||[],{id:s.appId,title:s.appId,logo:""}],hasApps:!0,appsLoaded:!0,hasAccess:!0}};case"APP_CREATE_FAILED":return{phase:"error",context:{...t.context,error:s.error,errorType:"ErrorCreatingApp"}};case"SET_ANONYMOUS":return{phase:"anonymous",context:{...t.context,isAnonymous:!0}};case"SET_SELECTED_APP":return localStorage.setItem("selectedApp",s.appId),"hasAccess"===t.phase?{...t,context:{...t.context,selectedApp:s.appId}}:{phase:"gettingApps",context:{...t.context,selectedApp:s.appId,hasApps:!1,appsLoaded:!1}};case"UPDATE_CONTEXT":{const e={...t.context,...s.updates},a=["authenticating","checkingCodicentAccess","registering","loadingUser","checkingPurchase","gettingApps","creatingApp","checkingAccess","notAuthenticated"];if("error"in s.updates&&s.updates.error&&a.includes(t.phase))return{phase:"error",context:e};if("needsPurchase"===t.phase&&"hasValidPurchase"in s.updates&&void 0===s.updates.hasValidPurchase)return{phase:"checkingPurchase",context:{...e,hasValidPurchase:void 0}};if("error"===t.phase&&"error"in s.updates&&null===s.updates.error){const s=t.context.errorType;let a="checkingCodicentAccess";return"ErrorLoadingUser"===s?a="loadingUser":"ErrorCheckingPurchase"===s?a="checkingPurchase":"ErrorGettingApps"===s?a="gettingApps":"ErrorCreatingApp"===s?a="creatingApp":"ErrorCheckingAccess"===s&&(a="checkingAccess"),{phase:a,context:{...e,error:null,errorType:void 0}}}return{...t,context:e}}case"CACHE_VALIDATED":return{...t,context:{...t.context,needsValidation:!1,isFromCache:!1}};case"CACHE_VALIDATION_FAILED":return s.lenient?{...t,context:{...t.context,needsValidation:!0}}:{phase:"authenticating",context:a()};default:return t}},exports.createInitialState=function(){if(e.getConfigValue("ENABLE_STATE_CACHE")){const s=t.stateMachineCacheManager.get("user_session");if(s&&function(e){if("object"!=typeof e||null===e)return!1;const t=e;return"string"==typeof t.nickname&&"string"==typeof t.selectedApp&&Array.isArray(t.apps)&&"boolean"==typeof t.isRegistered&&"boolean"==typeof t.hasValidPurchase}(s.data)){const t=s.data;return console.log("AppState: Restoring from cache",{nickname:t.nickname,selectedApp:t.selectedApp,appsCount:t.apps.length,age:Math.round((Date.now()-s.cachedAt)/1e3)+"s"}),{phase:"hasAccess",context:{...a(),nickname:t.nickname,name:t.name,selectedApp:t.selectedApp,apps:t.apps,hasValidPurchase:t.hasValidPurchase,isRegistered:t.isRegistered,hasAccess:!0,hasApps:t.apps.length>0,appsLoaded:!0,isFromCache:!0,needsValidation:Boolean(e.getConfigValue("VALIDATE_CACHE_IN_BACKGROUND"))}}}}return{phase:"authenticating",context:a()}},exports.isBusyPhase=e=>s.includes(e),exports.runBackgroundValidation=async function(t,s,a){try{const[c,r,o]=await Promise.all([t.getNickname().then((e=>e===s.nickname)).catch((()=>!1)),e.getConfigValue("SUBSCRIPTION_NEEDED")?t.checkSubscriptionStatus().then((e=>("active"===e||"trialing"===e)===s.hasValidPurchase)).catch((()=>!1)):Promise.resolve(!0),t.getApps().then((t=>{if(!t)return!1;const a=e.getConfigValue("APP_PREFIX")||void 0,n=a?t.filter((e=>e.id.startsWith(a))):t,c=s.apps||[];return n.length===c.length&&n.every((e=>c.some((t=>t.id===e.id))))})).catch((()=>!1))]);if(c&&r&&o)n(s),a({type:"CACHE_VALIDATED"});else{a({type:"CACHE_VALIDATION_FAILED",lenient:"strict"!==e.getConfigValue("CACHE_FAILURE_MODE")})}}catch{}},exports.saveSession=n;
@@ -1 +1 @@
1
- {"version":3,"file":"useAuthState.d.ts","sourceRoot":"","sources":["../../../src/hooks/useAuthState.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,QAAQ,EAAqB,MAAM,oBAAoB,CAAC;AAC9G,OAAO,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;AAUrC,MAAM,WAAW,YAAY;IAC3B,eAAe,EAAE,OAAO,CAAC;IACzB,YAAY,EAAE,OAAO,GAAG,SAAS,CAAC;IAClC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;IAInB,IAAI,EAAE,GAAG,CAAC;IACV,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,YAAY,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACpD,eAAe,EAAE,eAAe,CAAC;IACjC,iBAAiB,EAAE,CAAC,OAAO,CAAC,EAAE,oBAAoB,CAAC,QAAQ,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/E,iBAAiB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrD;AAED,MAAM,WAAW,gBAAgB;IAC/B,wFAAwF;IACxF,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC,CAAC;IACzG,8FAA8F;IAC9F,UAAU,CAAC,EAAE,CACX,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,KAChB,OAAO,CAAC,MAAM,CAAC,CAAC;CACtB;AAED,QAAA,MAAM,YAAY,UAAW,qBAAqB,YAAY,gBAAgB,KAAG,YA0RhF,CAAC;AAEF,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"useAuthState.d.ts","sourceRoot":"","sources":["../../../src/hooks/useAuthState.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,QAAQ,EAAqB,MAAM,oBAAoB,CAAC;AAC9G,OAAO,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;AAUrC,MAAM,WAAW,YAAY;IAC3B,eAAe,EAAE,OAAO,CAAC;IACzB,YAAY,EAAE,OAAO,GAAG,SAAS,CAAC;IAClC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;IAInB,IAAI,EAAE,GAAG,CAAC;IACV,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,YAAY,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACpD,eAAe,EAAE,eAAe,CAAC;IACjC,iBAAiB,EAAE,CAAC,OAAO,CAAC,EAAE,oBAAoB,CAAC,QAAQ,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/E,iBAAiB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrD;AAED,MAAM,WAAW,gBAAgB;IAC/B,wFAAwF;IACxF,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC,CAAC;IACzG,8FAA8F;IAC9F,UAAU,CAAC,EAAE,CACX,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,KAChB,OAAO,CAAC,MAAM,CAAC,CAAC;CACtB;AAED,QAAA,MAAM,YAAY,UAAW,qBAAqB,YAAY,gBAAgB,KAAG,YA+QhF,CAAC;AAEF,eAAe,YAAY,CAAC"}
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),r=require("../services/codicent.js");require("../components/Markdown.js"),require("../components/Textarea.js"),require("../components/Button.js"),require("../components/CompoundButton.js"),require("react/jsx-runtime"),require("@fluentui/react-components"),require("../components/Spinner.js"),require("../components/TextHeader.js"),require("../components/TypingIndicator.js"),require("../components/Dialog.js"),require("../components/ChatInput.js"),require("../components/CombinedPlaceholderDialog.js"),require("../components/ChatMessage.js"),require("../components/Header.js"),require("@fluentui/react-icons");var o=require("../config/index.js");require("../utils/MessageContent.js"),require("../node_modules/tinycolor2/esm/tinycolor.js"),require("../_virtual/index.js"),require("../utils/cacheManager.js"),require("../lib/wavtools/lib/wav_packer.js"),require("../lib/wavtools/lib/analysis/audio_analysis.js"),require("../lib/wavtools/lib/wav_stream_player.js"),require("../lib/wavtools/lib/wav_recorder.js"),require("./useLocalization.js"),require("./useAppStyles.js"),require("../components/FileThumbnail.js"),require("../components/MessageInput.js"),require("../components/UploadFile.js"),require("../components/SnapFooter.js"),require("../components/Profile.js"),require("../components/MessageItem.js"),require("../components/Content.js"),require("../components/AiInput.js"),require("../components/SearchBox.js"),require("../components/DataMessagePicker.js"),require("../components/HtmlView.js"),require("../components/Footer.js"),require("../components/Page.js"),require("../components/QrCodeDialog.js"),require("../components/QrScanner.js"),require("../components/OfflineMessage.js"),require("../components/LanguageSelector.js"),require("../components/ListView.js"),require("../components/RecordModal.js"),require("../components/BulkUploadDialog.js"),require("../components/CookieBanner.js"),require("../pages/AppFrame.js"),require("../pages/Chat.js"),require("../pages/Compose.js"),require("../pages/Snap.js"),require("../pages/Search.js"),require("../pages/Login.js"),require("../pages/CrmPage.js"),require("../pages/CrmPagePersistent.js"),require("../pages/ImageView.js"),require("../pages/FormInvite.js"),require("../pages/FormAccept.js"),require("../pages/Sales.js"),require("../pages/Purchase.js"),require("../pages/QrScan.js"),require("react-dom/client"),require("react-router-dom"),require("../node_modules/@auth0/auth0-react/dist/auth0-react.esm.js");exports.default=(s,n)=>{const{isAuthenticated:t,getAccessTokenSilently:i,user:a,isLoading:u,logout:c,getAccessTokenWithPopup:l,loginWithRedirect:g,loginWithPopup:p}=s,[q,m]=e.useState(null),[j,C]=e.useState(void 0),[E,P]=e.useState(null),[d,_]=e.useState(""),T=e.useMemo((()=>new r.CodicentService({API_BASE_URL:o.getConfigValue("API_BASE_URL"),PUBSUB_URL:o.getConfigValue("PUBSUB_URL"),APP_LOG_CODICENT:o.getConfigValue("APP_LOG_CODICENT"),APP_LOG_TOKEN:o.getConfigValue("APP_LOG_TOKEN"),APP_NAME:o.getConfigValue("APP_NAME"),APP_PREFIX:o.getConfigValue("APP_PREFIX"),APP_TEMPLATE:o.getConfigValue("APP_TEMPLATE"),BUTTON_TAG:o.getConfigValue("BUTTON_TAG"),STRIPE_PUBLIC_KEY:o.getConfigValue("STRIPE_PUBLIC_KEY"),STRIPE_SOURCE:o.getConfigValue("STRIPE_SOURCE"),STRIPE_TRIAL_PERIOD_DAYS:o.getConfigValue("STRIPE_TRIAL_PERIOD_DAYS"),SUBSCRIPTION_NEEDED:o.getConfigValue("SUBSCRIPTION_NEEDED"),USER_PREFIX:o.getConfigValue("USER_PREFIX"),ANONYMOUS_TOKEN:o.getConfigValue("ANONYMOUS_TOKEN")})),[]);e.useEffect((()=>{!u&&t&&(async()=>{try{const e=await i({});console.debug("CODICENT: ACCESS TOKEN",e),m(e)}catch(e){console.debug("CODICENT: Failed to get access token",e);const r=e;if(r&&"object"==typeof r&&"error"in r&&"login_required"===r.error)console.warn("CODICENT: Login required"),S();else if(r&&"object"==typeof r&&"error"in r&&"consent_required"===r.error)try{const e=await l();if(!e)return void P("Failed to get access token: no token from auth0 with popup");console.log("CODICENT: GOT ACCESS TOKEN"),m(e)}catch(e){console.warn("CODICENT: Failed to get access token with popup",e),S()}else P("Failed to get access token: "+(r.message?.toString()||r.toString())),console.log("CODICENT: ACCESS TOKEN ERROR",r)}})().then((()=>{}))}),[t,l,i,g,u]),e.useEffect((()=>{if(a&&a.sub&&q&&void 0===j){let e=!0;return(n?.loginFn?n.loginFn(T,a.sub,q):T.loginUser(a.sub,q)).then((r=>{e&&(null===r?C(!1):""===r?P("Kontrollera internetanslutningen och försök igen."):(T.setToken(r),T.getNickname().then(_),C(!0)))})).catch((()=>{e&&(P("Ett fel uppstod. Försök igen senare."),C(!1))})),()=>{e=!1}}}),[a,q,j,T]);const S=e.useCallback((()=>{T.logout(),m(null),P(null),C(void 0),_(""),c({logoutParams:{returnTo:o.getConfigValue("AUTH_REDIRECT_URL")}})}),[T,c]),f=e.useCallback((async e=>{const r=n?.registerFn?await n.registerFn(T,e,a.email,a.sub,q):await T.registerUser(e,a.email,a.sub,q);return r&&(T.setToken(r),C(!0)),r}),[T,a,q]);e.useEffect((()=>{T.onUnauthorized=S}),[T]);const A=e.useCallback((async e=>{try{await p({authorizationParams:{connection:"email",login_hint:e}})}catch(e){console.error("Passwordless login failed:",e),P(`Passwordless login failed: ${e}`)}}),[p]);return e.useMemo((()=>({isAuthenticated:t,isRegistered:j,accessToken:q,authError:E,isLoading:u,user:a,nickname:d,logout:S,registerUser:f,codicentService:T,loginWithRedirect:g,loginPasswordless:A})),[t,j,q,E,u,a,d,S,f,T,g,A])};
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),r=require("../services/codicent.js");require("../components/Markdown.js"),require("../components/Textarea.js"),require("../components/Button.js"),require("../components/CompoundButton.js"),require("react/jsx-runtime"),require("@fluentui/react-components"),require("../components/Spinner.js"),require("../components/TextHeader.js"),require("../components/TypingIndicator.js"),require("../components/Dialog.js"),require("../components/ChatInput.js"),require("../components/CombinedPlaceholderDialog.js"),require("../components/ChatMessage.js"),require("../components/Header.js"),require("@fluentui/react-icons");var o=require("../config/index.js");require("../utils/MessageContent.js"),require("../node_modules/tinycolor2/esm/tinycolor.js"),require("../_virtual/index.js"),require("../utils/cacheManager.js"),require("../lib/wavtools/lib/wav_packer.js"),require("../lib/wavtools/lib/analysis/audio_analysis.js"),require("../lib/wavtools/lib/wav_stream_player.js"),require("../lib/wavtools/lib/wav_recorder.js"),require("./useLocalization.js"),require("./useAppStyles.js"),require("../components/FileThumbnail.js"),require("../components/MessageInput.js"),require("../components/UploadFile.js"),require("../components/SnapFooter.js"),require("../components/Profile.js"),require("../components/MessageItem.js"),require("../components/Content.js"),require("../components/AiInput.js"),require("../components/SearchBox.js"),require("../components/DataMessagePicker.js"),require("../components/HtmlView.js"),require("../components/Footer.js"),require("../components/Page.js"),require("../components/QrCodeDialog.js"),require("../components/QrScanner.js"),require("../components/OfflineMessage.js"),require("../components/LanguageSelector.js"),require("../components/ListView.js"),require("../components/RecordModal.js"),require("../components/BulkUploadDialog.js"),require("../components/CookieBanner.js"),require("../pages/AppFrame.js"),require("../pages/Chat.js"),require("../pages/Compose.js"),require("../pages/Snap.js"),require("../pages/Search.js"),require("../pages/Login.js"),require("../pages/CrmPage.js"),require("../pages/CrmPagePersistent.js"),require("../pages/ImageView.js"),require("../pages/FormInvite.js"),require("../pages/FormAccept.js"),require("../pages/Sales.js"),require("../pages/Purchase.js"),require("../pages/QrScan.js"),require("react-dom/client"),require("react-router-dom"),require("../node_modules/@auth0/auth0-react/dist/auth0-react.esm.js");exports.default=(s,n)=>{const{isAuthenticated:t,getAccessTokenSilently:i,user:a,isLoading:u,logout:c,getAccessTokenWithPopup:l,loginWithRedirect:g,loginWithPopup:p}=s,[q,m]=e.useState(null),[j,C]=e.useState(void 0),[E,P]=e.useState(null),[d,_]=e.useState(""),S=e.useMemo((()=>new r.CodicentService({API_BASE_URL:o.getConfigValue("API_BASE_URL"),PUBSUB_URL:o.getConfigValue("PUBSUB_URL"),APP_LOG_CODICENT:o.getConfigValue("APP_LOG_CODICENT"),APP_LOG_TOKEN:o.getConfigValue("APP_LOG_TOKEN"),APP_NAME:o.getConfigValue("APP_NAME"),APP_PREFIX:o.getConfigValue("APP_PREFIX"),APP_TEMPLATE:o.getConfigValue("APP_TEMPLATE"),BUTTON_TAG:o.getConfigValue("BUTTON_TAG"),STRIPE_PUBLIC_KEY:o.getConfigValue("STRIPE_PUBLIC_KEY"),STRIPE_SOURCE:o.getConfigValue("STRIPE_SOURCE"),STRIPE_TRIAL_PERIOD_DAYS:o.getConfigValue("STRIPE_TRIAL_PERIOD_DAYS"),SUBSCRIPTION_NEEDED:o.getConfigValue("SUBSCRIPTION_NEEDED"),USER_PREFIX:o.getConfigValue("USER_PREFIX"),ANONYMOUS_TOKEN:o.getConfigValue("ANONYMOUS_TOKEN")})),[]);e.useEffect((()=>{!u&&t&&(async()=>{try{const e=await i({});console.debug("CODICENT: ACCESS TOKEN",e),m(e)}catch(e){console.debug("CODICENT: Failed to get access token",e);const r=e;if(r&&"object"==typeof r&&"error"in r&&"login_required"===r.error)console.warn("CODICENT: Session expired (login_required)"),m(null);else if(r&&"object"==typeof r&&"error"in r&&"consent_required"===r.error)try{const e=await l();if(!e)return void P("Failed to get access token: no token from auth0 with popup");console.log("CODICENT: GOT ACCESS TOKEN"),m(e)}catch(e){console.warn("CODICENT: Failed to get access token with popup",e),P("Samtycke krävs för inloggning. Tillåt popup-fönster och försök igen."),m(null)}else P("Failed to get access token: "+(r.message?.toString()||r.toString())),console.log("CODICENT: ACCESS TOKEN ERROR",r)}})().then((()=>{}))}),[t,l,i,g,u]),e.useEffect((()=>{if(a&&a.sub&&q&&void 0===j){let e=!0;return(n?.loginFn?n.loginFn(S,a.sub,q):S.loginUser(a.sub,q)).then((r=>{e&&(null===r?C(!1):""===r?P("Kontrollera internetanslutningen och försök igen."):(S.setToken(r),S.getNickname().then(_),C(!0)))})).catch((()=>{e&&(P("Ett fel uppstod. Försök igen senare."),C(!1))})),()=>{e=!1}}}),[a,q,j,S]);const T=e.useCallback((()=>{S.logout(),m(null),P(null),C(void 0),_(""),c({logoutParams:{returnTo:o.getConfigValue("AUTH_REDIRECT_URL")}})}),[S,c]),f=e.useCallback((async e=>{const r=n?.registerFn?await n.registerFn(S,e,a.email,a.sub,q):await S.registerUser(e,a.email,a.sub,q);return r&&(S.setToken(r),C(!0)),r}),[S,a,q]);e.useEffect((()=>{S.onUnauthorized=T}),[S]);const A=e.useCallback((async e=>{try{await p({authorizationParams:{connection:"email",login_hint:e}})}catch(e){console.error("Passwordless login failed:",e),P(`Passwordless login failed: ${e}`)}}),[p]);return e.useMemo((()=>({isAuthenticated:t,isRegistered:j,accessToken:q,authError:E,isLoading:u,user:a,nickname:d,logout:T,registerUser:f,codicentService:S,loginWithRedirect:g,loginPasswordless:A})),[t,j,q,E,u,a,d,T,f,S,g,A])};
@@ -1,6 +1,6 @@
1
1
  import { Auth0ContextInterface } from "@auth0/auth0-react";
2
2
  import { CodicentService } from "../services";
3
- import { AppStateMachine, StateContext, AppStateDefinition } from "../utils";
3
+ import AppStateMachine, { StateContext, AppStateDefinition } from "../utils/appState";
4
4
  import { AudioRecorderState } from "./useAudioRecorder";
5
5
  import { AuthStateOptions, UseAuthState } from "./useAuthState";
6
6
  import { RealtimeVoice } from "./useRealtimeVoiceAI";
@@ -1 +1 @@
1
- {"version":3,"file":"useCodicentApp.d.ts","sourceRoot":"","sources":["../../../src/hooks/useCodicentApp.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,kBAAkB,EAAyB,MAAM,UAAU,CAAC;AACpG,OAAyB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAqB,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9E,OAA2B,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACzE,OAAiB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAGnD,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,kBAAkB,CAAC;IAC1B,IAAI,EAAE,YAAY,CAAC;IACnB,YAAY,EAAE,eAAe,CAAC;IAC9B,OAAO,EAAE,eAAe,CAAC;IACzB,OAAO,EAAE,YAAY,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;IACnC,YAAY,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,SAAS,EAAE,kBAAkB,CAAC;IAC9B,MAAM,EAAE,MAAM,OAAO,CAAC;IACtB,KAAK,EAAE,aAAa,GAAG,SAAS,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,qBAAqB,CAAC;IAC7B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,WAAW,CAAC,EAAE,gBAAgB,CAAC;CAChC;AAED,eAAO,MAAM,cAAc,wCAAyC,qBAAqB,KAoMlF,gBACN,CAAC"}
1
+ {"version":3,"file":"useCodicentApp.d.ts","sourceRoot":"","sources":["../../../src/hooks/useCodicentApp.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,eAAe,EAAE,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACtF,OAAyB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAqB,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9E,OAA2B,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACzE,OAAiB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAanD,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,kBAAkB,CAAC;IAC1B,IAAI,EAAE,YAAY,CAAC;IACnB,YAAY,EAAE,eAAe,CAAC;IAC9B,OAAO,EAAE,eAAe,CAAC;IACzB,OAAO,EAAE,YAAY,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;IACnC,YAAY,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,SAAS,EAAE,kBAAkB,CAAC;IAC9B,MAAM,EAAE,MAAM,OAAO,CAAC;IACtB,KAAK,EAAE,aAAa,GAAG,SAAS,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,qBAAqB,CAAC;IAC7B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,WAAW,CAAC,EAAE,gBAAgB,CAAC;CAChC;AAED,eAAO,MAAM,cAAc,wCAAyC,qBAAqB,KA2WlF,gBACN,CAAC"}
@@ -1 +1 @@
1
- "use strict";var e=require("react");require("../utils/MessageContent.js"),require("../node_modules/tinycolor2/esm/tinycolor.js"),require("react/jsx-runtime");var t=require("../utils/appState.js");require("../_virtual/index.js"),require("../lib/wavtools/lib/wav_packer.js"),require("../lib/wavtools/lib/analysis/audio_analysis.js"),require("../lib/wavtools/lib/wav_stream_player.js"),require("../lib/wavtools/lib/wav_recorder.js"),require("../utils/cacheManager.js");var r=require("./useAudioRecorder.js"),s=require("./useAuthState.js"),n=require("./useRealtimeVoiceAI.js"),a=require("./useTools.js");exports.useCodicentApp=({auth0:c,toolsConfig:u,authOptions:i})=>{const o=s.default(c,i),l=e.useRef(null);l.current||(l.current=t.createAppStateMachine(o.codicentService,(()=>{})));const[d,m]=e.useState((()=>{let e="",t=l.current.getCurrentStateName(),r=0;for(;t!==e&&r<10;)l.current.update(),e=t,t=l.current.getCurrentStateName(),r++;return t})),{service:p,context:h}=l.current,{nickname:f,name:g,error:A,errorType:k,selectedApp:C}=h,S=e.useCallback(((e,t)=>{const r=e.get("file").name;p.uploadFile(r,e).then((e=>{p.sendMessage(`#transcribe ${""!==t?(t.startsWith("#")?"":"#")+t+" ":""}#file:${e}`).then((()=>{})).catch(console.warn)}))}),[p]),v=r.useAudioRecorder(S),[b,q]=e.useState(),[w,j]=e.useState(),[y,x]=e.useState(!1),N=e.useMemo((()=>new Audio("./notification.mp3")),[]),T=e.useCallback((()=>x(!0)),[]),R=a.default(p,q,j,N,b,T,u),M=n.default(p,R);e.useEffect((()=>{y&&(M?.disconnectConversation(),x(!1))}),[y,M]),e.useEffect((()=>{o.isAuthenticated&&o.user&&o.accessToken&&l.current.updateContext({isAuthenticated:o.isAuthenticated,user:{sub:o.user.sub,email:o.user.email},accessToken:o.accessToken})}),[o.isAuthenticated,o.user,o.accessToken]);const _=e.useRef(o.isAuthenticated);e.useEffect((()=>{const e=!0===_.current,t=!0===o.isAuthenticated;e&&!t&&l.current.logout(),_.current=o.isAuthenticated}),[o.isAuthenticated]),e.useEffect((()=>l.current.updateContext({nickname:o.nickname})),[o.nickname]),e.useEffect((()=>{l.current.update();let e,t=l.current.getCurrentStateName();m(l.current.getCurrentStateName()),JSON.stringify(l.current.context);let r="hasAccess"===l.current.getCurrentStateName();const s=n=>setInterval((()=>{const n=l.current.getCurrentStateName();"hasAccess"!==n||r?"hasAccess"!==n&&r&&(console.log("🚨 Left stable state - switching to fast polling (200ms)"),r=!1,clearInterval(e),e=s(200)):(console.log("🎯 Reached stable state - switching to slower polling (1000ms)"),r=!0,clearInterval(e),e=s(1e3));const a=JSON.stringify(l.current.context);l.current.update();const c=JSON.stringify(l.current.context),u=l.current.getCurrentStateName();u===t&&a===c||(m(u),t=u)}),n);return e=s(r?1e3:200),()=>clearInterval(e)}),[]);const I=e.useCallback((e=>e.replace("{nickname}",f||"unknown").replace("{token}",encodeURIComponent(o.accessToken||"unknown")).replace("{app}",C||"unknown")),[f,o.accessToken,C]),E=e.useCallback((e=>{l.current.updateContext({isAnonymous:e})}),[]),O=e.useCallback((()=>l.current.isBusy()),[]);return e.useMemo((()=>({audio:v,auth:o,currentStateName:d,stateMachine:l.current,service:p,context:h,state:d,nickname:f,name:g,error:A,errorType:k,fixAppUrl:I,setAnonymous:E,allStates:l.current.allStates,isBusy:O,voice:M,html:b,setHtml:q,script:w})),[d,f,g,A,k,b,w,o.isAuthenticated,o.isLoading,v.isRecording,M?.isConnected,I,E,O])};
1
+ "use strict";var e=require("react"),t=require("./useAudioRecorder.js"),r=require("./useAuthState.js"),s=require("./useRealtimeVoiceAI.js"),n=require("./useTools.js"),a=require("../config/index.js"),c=require("../utils/cacheManager.js"),i=require("./useAppState.js");exports.useCodicentApp=({auth0:o,toolsConfig:u,authOptions:p})=>{const l=r.default(o,p),A=l.codicentService,[{phase:E,context:d},f]=e.useReducer(i.appStateReducer,null,i.createInitialState),T=e.useCallback(((e,t)=>{const r=e.get("file").name;A.uploadFile(r,e).then((e=>{A.sendMessage(`#transcribe ${""!==t?(t.startsWith("#")?"":"#")+t+" ":""}#file:${e}`).catch(console.warn)}))}),[A]),g=t.useAudioRecorder(T),[m,h]=e.useState(),[S,k]=e.useState(),[C,y]=e.useState(!1),R=e.useMemo((()=>new Audio("./notification.mp3")),[]),_=e.useCallback((()=>y(!0)),[]),I=n.default(A,h,k,R,m,_,u),U=s.default(A,I);e.useEffect((()=>{C&&(U?.disconnectConversation(),y(!1))}),[C,U]),e.useEffect((()=>{l.isLoading||(l.isAuthenticated&&l.accessToken?f({type:"AUTHENTICATED",accessToken:l.accessToken,user:{sub:l.user?.sub??"",email:l.user?.email??""}}):l.isAuthenticated?l.authError&&f({type:"UPDATE_CONTEXT",updates:{error:l.authError}}):f({type:"NOT_AUTHENTICATED"}))}),[l.isLoading,l.isAuthenticated,l.accessToken,l.authError]),e.useEffect((()=>{"checkingCodicentAccess"===E&&(void 0===l.isRegistered&&l.authError?f({type:"UPDATE_CONTEXT",updates:{error:l.authError,errorType:"CodicentLoginFailed"}}):void 0!==l.isRegistered&&(!0===l.isRegistered&&l.nickname?f({type:"REGISTERED",nickname:l.nickname}):!1===l.isRegistered&&f({type:"NOT_REGISTERED"})))}),[E,l.isRegistered,l.nickname,l.authError]),e.useEffect((()=>{if("registering"!==E)return;if(!d.accessToken||!d.user)return;let e=!1;return A.setToken(d.accessToken),A.findUsername().then((async t=>{if(e)return;if(!t)return void f({type:"REGISTER_AUTO_FAIL",error:"Användarnamn kunde inte hittas.",errorType:"NoUsernameFound"});const r=await A.nicknameExists(t);e||(r?f({type:"REGISTER_AUTO_FAIL",error:"Användarnamnet finns redan.",errorType:"UsernameExists"}):(await A.registerUser(t,d.user.email,d.user.sub,d.accessToken),e||(A.setToken(d.accessToken),f({type:"REGISTER_AUTO_SUCCESS",nickname:t}))))})).catch((t=>{e||f({type:"REGISTER_AUTO_FAIL",error:t instanceof Error?t.message:String(t),errorType:"ErrorRegistering"})})),()=>{e=!0}}),[E]),e.useEffect((()=>{if("loadingUser"!==E||!d.nickname)return;let e=!1;return localStorage.setItem("nickname",d.nickname),A.getUserInfo(d.nickname).then((t=>{e||f({type:"USER_LOADED",name:t?.name||t?.nickname||""})})).catch((()=>{e||f({type:"USER_LOADED",name:""})})),()=>{e=!0}}),[E]),e.useEffect((()=>{if("checkingPurchase"!==E)return;if(!a.getConfigValue("SUBSCRIPTION_NEEDED"))return void f({type:"PURCHASE_VALID"});let e=!1;return A.checkSubscriptionStatus().then((t=>{if(!e){f("active"===t||"trialing"===t?{type:"PURCHASE_VALID"}:{type:"PURCHASE_INVALID"})}})).catch((()=>{e||f({type:"PURCHASE_INVALID"})})),()=>{e=!0}}),[E]),e.useEffect((()=>{if("gettingApps"!==E)return;let e=!1;return A.getApps().then((t=>{e||f(null!==t?{type:"APPS_LOADED",apps:t}:{type:"APPS_FAILED",error:"Failed to fetch apps."})})).catch((t=>{e||f({type:"APPS_FAILED",error:String(t)})})),()=>{e=!0}}),[E]),e.useEffect((()=>{if("creatingApp"!==E)return;let e=!1;return A.createApp().then((t=>{e||f(t?{type:"APP_CREATED",appId:t}:{type:"APP_CREATE_FAILED",error:"Misslyckades att skapa din app. Försök igen senare."})})).catch((t=>{e||f({type:"APP_CREATE_FAILED",error:String(t)})})),()=>{e=!0}}),[E]),e.useEffect((()=>{"hasAccess"===E&&d.selectedApp&&(A.codicent=d.selectedApp,localStorage.setItem("selectedApp",d.selectedApp),d.isFromCache||i.saveSession(d))}),[E,d.selectedApp]);const O=e.useRef(!1);e.useEffect((()=>{"hasAccess"===E&&d.isFromCache&&d.needsValidation&&l.accessToken&&l.isAuthenticated&&(O.current||(O.current=!0,i.runBackgroundValidation(A,d,f)))}),[E,d.isFromCache,d.needsValidation,l.accessToken,l.isAuthenticated]),e.useEffect((()=>{"needsPurchase"===E&&(window.location.href="./#/purchase")}),[E]),e.useEffect((()=>{if("anonymous"!==E)return;const e=a.getConfigValue("ANONYMOUS_TOKEN"),t=a.getConfigValue("ANONYMOUS_CODICENT")||a.getConfigValue("APP_NAME")||"";e&&(A.setToken(e),A.codicent=t)}),[E]),e.useEffect((()=>{"loggingOut"===E&&(a.getConfigValue("ENABLE_STATE_CACHE")&&c.stateMachineCacheManager.clear(),localStorage.removeItem("selectedApp"),localStorage.removeItem("nickname"),localStorage.removeItem("codicent"),sessionStorage.clear(),l.logout())}),[E]);const P=e.useRef(d);P.current=d;const D=e.useRef({}).current,N=e.useRef({}).current,L=e.useMemo((()=>({service:A,get context(){return P.current},current:"hasAccess"===E?D:N,allStates:{hasAccess:D},setSelectedApp:e=>{f({type:"SET_SELECTED_APP",appId:e})},updateContext:e=>{f({type:"UPDATE_CONTEXT",updates:e})},logout:()=>{f({type:"LOGOUT"})},update:()=>{},isBusy:()=>i.isBusyPhase(E)})),[E,A]),v=e.useCallback((e=>e.replace("{nickname}",d.nickname||"unknown").replace("{token}",encodeURIComponent(l.accessToken||"unknown")).replace("{app}",d.selectedApp||"unknown")),[d.nickname,l.accessToken,d.selectedApp]),F=e.useCallback((e=>{e&&a.getConfigValue("ANONYMOUS_TOKEN")&&f({type:"SET_ANONYMOUS"})}),[]),M=e.useCallback((()=>i.isBusyPhase(E)),[E]);return e.useMemo((()=>({audio:g,auth:l,currentStateName:E,stateMachine:L,service:A,context:d,state:E,nickname:d.nickname||"",name:d.name||"",error:d.error||"",errorType:d.errorType||"",fixAppUrl:v,setAnonymous:F,allStates:L.allStates,isBusy:M,voice:U,html:m||"",setHtml:h,script:S||""})),[E,d,m,S,l.isAuthenticated,l.isLoading,g.isRecording,U?.isConnected,v,F,M,L])};
@@ -0,0 +1,81 @@
1
+ import { Dispatch } from "react";
2
+ import { AppInfo, CodicentService } from "../services/codicent";
3
+ import { StateContext } from "../utils/appState";
4
+ export type AppPhase = "authenticating" | "notAuthenticated" | "checkingCodicentAccess" | "registering" | "registered" | "loadingUser" | "checkingPurchase" | "needsPurchase" | "gettingApps" | "creatingApp" | "checkingAccess" | "noAccess" | "hasAccess" | "loggingOut" | "error" | "anonymous" | "restoringFromCache" | "validatingCache";
5
+ export type AppAction = {
6
+ type: "LOGOUT";
7
+ } | {
8
+ type: "NOT_AUTHENTICATED";
9
+ } | {
10
+ type: "AUTHENTICATED";
11
+ accessToken: string;
12
+ user: {
13
+ sub: string;
14
+ email: string;
15
+ };
16
+ } | {
17
+ type: "REGISTERED";
18
+ nickname: string;
19
+ } | {
20
+ type: "NOT_REGISTERED";
21
+ } | {
22
+ type: "REGISTER_AUTO_SUCCESS";
23
+ nickname: string;
24
+ } | {
25
+ type: "REGISTER_AUTO_FAIL";
26
+ error: string;
27
+ errorType?: StateContext["errorType"];
28
+ } | {
29
+ type: "USER_LOADED";
30
+ name: string;
31
+ } | {
32
+ type: "PURCHASE_VALID";
33
+ } | {
34
+ type: "PURCHASE_INVALID";
35
+ } | {
36
+ type: "APPS_LOADED";
37
+ apps: AppInfo[];
38
+ } | {
39
+ type: "APPS_FAILED";
40
+ error: string;
41
+ } | {
42
+ type: "APP_CREATED";
43
+ appId: string;
44
+ } | {
45
+ type: "APP_CREATE_FAILED";
46
+ error: string;
47
+ } | {
48
+ type: "SET_ANONYMOUS";
49
+ } | {
50
+ type: "SET_SELECTED_APP";
51
+ appId: string;
52
+ } | {
53
+ type: "UPDATE_CONTEXT";
54
+ updates: Partial<StateContext>;
55
+ } | {
56
+ type: "CACHE_VALIDATED";
57
+ } | {
58
+ type: "CACHE_VALIDATION_FAILED";
59
+ lenient: boolean;
60
+ };
61
+ export interface AppReducerState {
62
+ phase: AppPhase;
63
+ context: StateContext;
64
+ }
65
+ /** Phases where isBusy() should return true */
66
+ export declare const BUSY_PHASES: AppPhase[];
67
+ export declare const isBusyPhase: (phase: AppPhase) => boolean;
68
+ export declare function appStateReducer(state: AppReducerState, action: AppAction): AppReducerState;
69
+ /**
70
+ * Creates the initial reducer state. Reads the cache synchronously so the
71
+ * very first render is already in the correct phase (no flicker).
72
+ */
73
+ export declare function createInitialState(): AppReducerState;
74
+ /** Persist the current session to localStorage cache. */
75
+ export declare function saveSession(context: StateContext): void;
76
+ /**
77
+ * Runs the three background validation checks (registration, purchase, apps)
78
+ * after restoring from cache. Dispatches CACHE_VALIDATED or CACHE_VALIDATION_FAILED.
79
+ */
80
+ export declare function runBackgroundValidation(service: CodicentService, context: StateContext, dispatch: Dispatch<AppAction>): Promise<void>;
81
+ //# sourceMappingURL=useAppState.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAppState.d.ts","sourceRoot":"","sources":["../../../src/hooks/useAppState.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ import{getConfigValue as e}from"../config/index.js";import{stateMachineCacheManager as t}from"../utils/cacheManager.js";const s=["checkingCodicentAccess","registering","loadingUser","checkingPurchase","gettingApps","creatingApp","checkingAccess","loggingOut"],n=e=>s.includes(e);function c(){const t={isAuthenticated:!1,isRegistered:void 0,hasValidPurchase:void 0,hasAccess:!1,selectedApp:void 0,error:null,errorType:void 0,accessToken:void 0,nickname:void 0,apps:[],hasApps:!1,appsLoaded:!1,user:void 0,name:void 0,isAnonymous:void 0,isFromCache:void 0,needsValidation:void 0};return e("APP_NAME")?localStorage.removeItem("selectedApp"):t.selectedApp=localStorage.getItem("selectedApp")||void 0,e("APP_PREFIX")&&t.selectedApp&&!t.selectedApp.startsWith(e("APP_PREFIX"))&&(t.selectedApp=void 0),t}function a(t,s){switch(s.type){case"LOGOUT":return{phase:"loggingOut",context:c()};case"NOT_AUTHENTICATED":return"loggingOut"===t.phase||"anonymous"===t.phase?t:"hasAccess"===t.phase?{phase:"loggingOut",context:c()}:{phase:"notAuthenticated",context:c()};case"AUTHENTICATED":{const{accessToken:e,user:n}=s;return"anonymous"===t.phase?t:"hasAccess"===t.phase&&t.context.isFromCache?{...t,context:{...t.context,accessToken:e,user:n,isAuthenticated:!0}}:"hasAccess"===t.phase?t:{phase:"checkingCodicentAccess",context:{...t.context,isAuthenticated:!0,accessToken:e,user:n}}}case"REGISTERED":case"REGISTER_AUTO_SUCCESS":return localStorage.setItem("nickname",s.nickname),{phase:"loadingUser",context:{...t.context,isRegistered:!0,nickname:s.nickname}};case"NOT_REGISTERED":return{phase:"registering",context:{...t.context,isRegistered:!1}};case"REGISTER_AUTO_FAIL":return{phase:"error",context:{...t.context,error:s.error,errorType:s.errorType}};case"USER_LOADED":return{phase:e("SUBSCRIPTION_NEEDED")?"checkingPurchase":"gettingApps",context:{...t.context,name:s.name}};case"PURCHASE_VALID":return{phase:"gettingApps",context:{...t.context,hasValidPurchase:!0}};case"PURCHASE_INVALID":return{phase:"needsPurchase",context:{...t.context,hasValidPurchase:!1}};case"APPS_LOADED":{const{apps:n}=s,c=e("APP_NAME")||void 0,a=e("APP_PREFIX")||void 0,r=a?n.filter((e=>e.id.startsWith(a))):n;if(0===r.length&&!c)return{phase:"creatingApp",context:{...t.context,apps:r,hasApps:!1,appsLoaded:!0,selectedApp:void 0}};const o=function(e,t,s){return s?e.some((e=>e.id===s))?s:null:t&&e.some((e=>e.id===t))?t:e.length>0?e[0].id:null}(r,t.context.selectedApp,c);return o?{phase:"hasAccess",context:{...t.context,apps:r,hasApps:!0,appsLoaded:!0,selectedApp:o,hasAccess:!0}}:{phase:"noAccess",context:{...t.context,apps:r,hasApps:r.length>0,appsLoaded:!0}}}case"APPS_FAILED":return{phase:"error",context:{...t.context,error:s.error,errorType:"ErrorGettingApps"}};case"APP_CREATED":return{phase:"hasAccess",context:{...t.context,selectedApp:s.appId,apps:[...t.context.apps||[],{id:s.appId,title:s.appId,logo:""}],hasApps:!0,appsLoaded:!0,hasAccess:!0}};case"APP_CREATE_FAILED":return{phase:"error",context:{...t.context,error:s.error,errorType:"ErrorCreatingApp"}};case"SET_ANONYMOUS":return{phase:"anonymous",context:{...t.context,isAnonymous:!0}};case"SET_SELECTED_APP":return localStorage.setItem("selectedApp",s.appId),"hasAccess"===t.phase?{...t,context:{...t.context,selectedApp:s.appId}}:{phase:"gettingApps",context:{...t.context,selectedApp:s.appId,hasApps:!1,appsLoaded:!1}};case"UPDATE_CONTEXT":{const e={...t.context,...s.updates},n=["authenticating","checkingCodicentAccess","registering","loadingUser","checkingPurchase","gettingApps","creatingApp","checkingAccess","notAuthenticated"];if("error"in s.updates&&s.updates.error&&n.includes(t.phase))return{phase:"error",context:e};if("needsPurchase"===t.phase&&"hasValidPurchase"in s.updates&&void 0===s.updates.hasValidPurchase)return{phase:"checkingPurchase",context:{...e,hasValidPurchase:void 0}};if("error"===t.phase&&"error"in s.updates&&null===s.updates.error){const s=t.context.errorType;let n="checkingCodicentAccess";return"ErrorLoadingUser"===s?n="loadingUser":"ErrorCheckingPurchase"===s?n="checkingPurchase":"ErrorGettingApps"===s?n="gettingApps":"ErrorCreatingApp"===s?n="creatingApp":"ErrorCheckingAccess"===s&&(n="checkingAccess"),{phase:n,context:{...e,error:null,errorType:void 0}}}return{...t,context:e}}case"CACHE_VALIDATED":return{...t,context:{...t.context,needsValidation:!1,isFromCache:!1}};case"CACHE_VALIDATION_FAILED":return s.lenient?{...t,context:{...t.context,needsValidation:!0}}:{phase:"authenticating",context:c()};default:return t}}function r(){if(e("ENABLE_STATE_CACHE")){const s=t.get("user_session");if(s&&function(e){if("object"!=typeof e||null===e)return!1;const t=e;return"string"==typeof t.nickname&&"string"==typeof t.selectedApp&&Array.isArray(t.apps)&&"boolean"==typeof t.isRegistered&&"boolean"==typeof t.hasValidPurchase}(s.data)){const t=s.data;return console.log("AppState: Restoring from cache",{nickname:t.nickname,selectedApp:t.selectedApp,appsCount:t.apps.length,age:Math.round((Date.now()-s.cachedAt)/1e3)+"s"}),{phase:"hasAccess",context:{...c(),nickname:t.nickname,name:t.name,selectedApp:t.selectedApp,apps:t.apps,hasValidPurchase:t.hasValidPurchase,isRegistered:t.isRegistered,hasAccess:!0,hasApps:t.apps.length>0,appsLoaded:!0,isFromCache:!0,needsValidation:Boolean(e("VALIDATE_CACHE_IN_BACKGROUND"))}}}}return{phase:"authenticating",context:c()}}function o(s){if(!e("ENABLE_STATE_CACHE"))return;if(!s.nickname||!s.selectedApp)return;const n={nickname:s.nickname,name:s.name||"",selectedApp:s.selectedApp,apps:s.apps||[],hasValidPurchase:s.hasValidPurchase||!1,isRegistered:s.isRegistered||!1,cachedAt:Date.now(),expiresAt:Date.now()+e("SESSION_CACHE_TTL"),version:"1.0.0"};t.set("user_session",n,e("SESSION_CACHE_TTL")),console.log("AppState: Saved session to cache")}async function p(t,s,n){try{const[c,a,r]=await Promise.all([t.getNickname().then((e=>e===s.nickname)).catch((()=>!1)),e("SUBSCRIPTION_NEEDED")?t.checkSubscriptionStatus().then((e=>("active"===e||"trialing"===e)===s.hasValidPurchase)).catch((()=>!1)):Promise.resolve(!0),t.getApps().then((t=>{if(!t)return!1;const n=e("APP_PREFIX")||void 0,c=n?t.filter((e=>e.id.startsWith(n))):t,a=s.apps||[];return c.length===a.length&&c.every((e=>a.some((t=>t.id===e.id))))})).catch((()=>!1))]);if(c&&a&&r)o(s),n({type:"CACHE_VALIDATED"});else{n({type:"CACHE_VALIDATION_FAILED",lenient:"strict"!==e("CACHE_FAILURE_MODE")})}}catch{}}export{s as BUSY_PHASES,a as appStateReducer,r as createInitialState,n as isBusyPhase,p as runBackgroundValidation,o as saveSession};
@@ -1 +1 @@
1
- {"version":3,"file":"useAuthState.d.ts","sourceRoot":"","sources":["../../../src/hooks/useAuthState.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,QAAQ,EAAqB,MAAM,oBAAoB,CAAC;AAC9G,OAAO,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;AAUrC,MAAM,WAAW,YAAY;IAC3B,eAAe,EAAE,OAAO,CAAC;IACzB,YAAY,EAAE,OAAO,GAAG,SAAS,CAAC;IAClC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;IAInB,IAAI,EAAE,GAAG,CAAC;IACV,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,YAAY,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACpD,eAAe,EAAE,eAAe,CAAC;IACjC,iBAAiB,EAAE,CAAC,OAAO,CAAC,EAAE,oBAAoB,CAAC,QAAQ,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/E,iBAAiB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrD;AAED,MAAM,WAAW,gBAAgB;IAC/B,wFAAwF;IACxF,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC,CAAC;IACzG,8FAA8F;IAC9F,UAAU,CAAC,EAAE,CACX,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,KAChB,OAAO,CAAC,MAAM,CAAC,CAAC;CACtB;AAED,QAAA,MAAM,YAAY,UAAW,qBAAqB,YAAY,gBAAgB,KAAG,YA0RhF,CAAC;AAEF,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"useAuthState.d.ts","sourceRoot":"","sources":["../../../src/hooks/useAuthState.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,QAAQ,EAAqB,MAAM,oBAAoB,CAAC;AAC9G,OAAO,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;AAUrC,MAAM,WAAW,YAAY;IAC3B,eAAe,EAAE,OAAO,CAAC;IACzB,YAAY,EAAE,OAAO,GAAG,SAAS,CAAC;IAClC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;IAInB,IAAI,EAAE,GAAG,CAAC;IACV,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,YAAY,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACpD,eAAe,EAAE,eAAe,CAAC;IACjC,iBAAiB,EAAE,CAAC,OAAO,CAAC,EAAE,oBAAoB,CAAC,QAAQ,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/E,iBAAiB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrD;AAED,MAAM,WAAW,gBAAgB;IAC/B,wFAAwF;IACxF,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC,CAAC;IACzG,8FAA8F;IAC9F,UAAU,CAAC,EAAE,CACX,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,KAChB,OAAO,CAAC,MAAM,CAAC,CAAC;CACtB;AAED,QAAA,MAAM,YAAY,UAAW,qBAAqB,YAAY,gBAAgB,KAAG,YA+QhF,CAAC;AAEF,eAAe,YAAY,CAAC"}
@@ -1 +1 @@
1
- import{useState as o,useMemo as e,useEffect as t,useCallback as s}from"react";import{CodicentService as n}from"../services/codicent.js";import"../components/Markdown.js";import"../components/Textarea.js";import"../components/Button.js";import"../components/CompoundButton.js";import"react/jsx-runtime";import"@fluentui/react-components";import"../components/Spinner.js";import"../components/TextHeader.js";import"../components/TypingIndicator.js";import"../components/Dialog.js";import"../components/ChatInput.js";import"../components/CombinedPlaceholderDialog.js";import"../components/ChatMessage.js";import"../components/Header.js";import"@fluentui/react-icons";import{getConfigValue as i}from"../config/index.js";import"../utils/MessageContent.js";import"../node_modules/tinycolor2/esm/tinycolor.js";import"../_virtual/index.js";import"../utils/cacheManager.js";import"../lib/wavtools/lib/wav_packer.js";import"../lib/wavtools/lib/analysis/audio_analysis.js";import"../lib/wavtools/lib/wav_stream_player.js";import"../lib/wavtools/lib/wav_recorder.js";import"./useLocalization.js";import"./useAppStyles.js";import"../components/FileThumbnail.js";import"../components/MessageInput.js";import"../components/UploadFile.js";import"../components/SnapFooter.js";import"../components/Profile.js";import"../components/MessageItem.js";import"../components/Content.js";import"../components/AiInput.js";import"../components/SearchBox.js";import"../components/DataMessagePicker.js";import"../components/HtmlView.js";import"../components/Footer.js";import"../components/Page.js";import"../components/QrCodeDialog.js";import"../components/QrScanner.js";import"../components/OfflineMessage.js";import"../components/LanguageSelector.js";import"../components/ListView.js";import"../components/RecordModal.js";import"../components/BulkUploadDialog.js";import"../components/CookieBanner.js";import"../pages/AppFrame.js";import"../pages/Chat.js";import"../pages/Compose.js";import"../pages/Snap.js";import"../pages/Search.js";import"../pages/Login.js";import"../pages/CrmPage.js";import"../pages/CrmPagePersistent.js";import"../pages/ImageView.js";import"../pages/FormInvite.js";import"../pages/FormAccept.js";import"../pages/Sales.js";import"../pages/Purchase.js";import"../pages/QrScan.js";import"react-dom/client";import"react-router-dom";import"../node_modules/@auth0/auth0-react/dist/auth0-react.esm.js";const r=(r,p)=>{const{isAuthenticated:a,getAccessTokenSilently:m,user:c,isLoading:l,logout:g,getAccessTokenWithPopup:u,loginWithRedirect:j,loginWithPopup:P}=r,[E,d]=o(null),[_,T]=o(void 0),[S,C]=o(null),[A,I]=o(""),O=e((()=>new n({API_BASE_URL:i("API_BASE_URL"),PUBSUB_URL:i("PUBSUB_URL"),APP_LOG_CODICENT:i("APP_LOG_CODICENT"),APP_LOG_TOKEN:i("APP_LOG_TOKEN"),APP_NAME:i("APP_NAME"),APP_PREFIX:i("APP_PREFIX"),APP_TEMPLATE:i("APP_TEMPLATE"),BUTTON_TAG:i("BUTTON_TAG"),STRIPE_PUBLIC_KEY:i("STRIPE_PUBLIC_KEY"),STRIPE_SOURCE:i("STRIPE_SOURCE"),STRIPE_TRIAL_PERIOD_DAYS:i("STRIPE_TRIAL_PERIOD_DAYS"),SUBSCRIPTION_NEEDED:i("SUBSCRIPTION_NEEDED"),USER_PREFIX:i("USER_PREFIX"),ANONYMOUS_TOKEN:i("ANONYMOUS_TOKEN")})),[]);t((()=>{!l&&a&&(async()=>{try{const o=await m({});console.debug("CODICENT: ACCESS TOKEN",o),d(o)}catch(o){console.debug("CODICENT: Failed to get access token",o);const e=o;if(e&&"object"==typeof e&&"error"in e&&"login_required"===e.error)console.warn("CODICENT: Login required"),R();else if(e&&"object"==typeof e&&"error"in e&&"consent_required"===e.error)try{const o=await u();if(!o)return void C("Failed to get access token: no token from auth0 with popup");console.log("CODICENT: GOT ACCESS TOKEN"),d(o)}catch(o){console.warn("CODICENT: Failed to get access token with popup",o),R()}else C("Failed to get access token: "+(e.message?.toString()||e.toString())),console.log("CODICENT: ACCESS TOKEN ERROR",e)}})().then((()=>{}))}),[a,u,m,j,l]),t((()=>{if(c&&c.sub&&E&&void 0===_){let o=!0;return(p?.loginFn?p.loginFn(O,c.sub,E):O.loginUser(c.sub,E)).then((e=>{o&&(null===e?T(!1):""===e?C("Kontrollera internetanslutningen och försök igen."):(O.setToken(e),O.getNickname().then(I),T(!0)))})).catch((()=>{o&&(C("Ett fel uppstod. Försök igen senare."),T(!1))})),()=>{o=!1}}}),[c,E,_,O]);const R=s((()=>{O.logout(),d(null),C(null),T(void 0),I(""),g({logoutParams:{returnTo:i("AUTH_REDIRECT_URL")}})}),[O,g]),h=s((async o=>{const e=p?.registerFn?await p.registerFn(O,o,c.email,c.sub,E):await O.registerUser(o,c.email,c.sub,E);return e&&(O.setToken(e),T(!0)),e}),[O,c,E]);t((()=>{O.onUnauthorized=R}),[O]);const N=s((async o=>{try{await P({authorizationParams:{connection:"email",login_hint:o}})}catch(o){console.error("Passwordless login failed:",o),C(`Passwordless login failed: ${o}`)}}),[P]);return e((()=>({isAuthenticated:a,isRegistered:_,accessToken:E,authError:S,isLoading:l,user:c,nickname:A,logout:R,registerUser:h,codicentService:O,loginWithRedirect:j,loginPasswordless:N})),[a,_,E,S,l,c,A,R,h,O,j,N])};export{r as default};
1
+ import{useState as o,useMemo as e,useEffect as t,useCallback as s}from"react";import{CodicentService as n}from"../services/codicent.js";import"../components/Markdown.js";import"../components/Textarea.js";import"../components/Button.js";import"../components/CompoundButton.js";import"react/jsx-runtime";import"@fluentui/react-components";import"../components/Spinner.js";import"../components/TextHeader.js";import"../components/TypingIndicator.js";import"../components/Dialog.js";import"../components/ChatInput.js";import"../components/CombinedPlaceholderDialog.js";import"../components/ChatMessage.js";import"../components/Header.js";import"@fluentui/react-icons";import{getConfigValue as i}from"../config/index.js";import"../utils/MessageContent.js";import"../node_modules/tinycolor2/esm/tinycolor.js";import"../_virtual/index.js";import"../utils/cacheManager.js";import"../lib/wavtools/lib/wav_packer.js";import"../lib/wavtools/lib/analysis/audio_analysis.js";import"../lib/wavtools/lib/wav_stream_player.js";import"../lib/wavtools/lib/wav_recorder.js";import"./useLocalization.js";import"./useAppStyles.js";import"../components/FileThumbnail.js";import"../components/MessageInput.js";import"../components/UploadFile.js";import"../components/SnapFooter.js";import"../components/Profile.js";import"../components/MessageItem.js";import"../components/Content.js";import"../components/AiInput.js";import"../components/SearchBox.js";import"../components/DataMessagePicker.js";import"../components/HtmlView.js";import"../components/Footer.js";import"../components/Page.js";import"../components/QrCodeDialog.js";import"../components/QrScanner.js";import"../components/OfflineMessage.js";import"../components/LanguageSelector.js";import"../components/ListView.js";import"../components/RecordModal.js";import"../components/BulkUploadDialog.js";import"../components/CookieBanner.js";import"../pages/AppFrame.js";import"../pages/Chat.js";import"../pages/Compose.js";import"../pages/Snap.js";import"../pages/Search.js";import"../pages/Login.js";import"../pages/CrmPage.js";import"../pages/CrmPagePersistent.js";import"../pages/ImageView.js";import"../pages/FormInvite.js";import"../pages/FormAccept.js";import"../pages/Sales.js";import"../pages/Purchase.js";import"../pages/QrScan.js";import"react-dom/client";import"react-router-dom";import"../node_modules/@auth0/auth0-react/dist/auth0-react.esm.js";const r=(r,p)=>{const{isAuthenticated:a,getAccessTokenSilently:m,user:c,isLoading:l,logout:g,getAccessTokenWithPopup:u,loginWithRedirect:j,loginWithPopup:P}=r,[E,d]=o(null),[_,T]=o(void 0),[S,C]=o(null),[A,I]=o(""),h=e((()=>new n({API_BASE_URL:i("API_BASE_URL"),PUBSUB_URL:i("PUBSUB_URL"),APP_LOG_CODICENT:i("APP_LOG_CODICENT"),APP_LOG_TOKEN:i("APP_LOG_TOKEN"),APP_NAME:i("APP_NAME"),APP_PREFIX:i("APP_PREFIX"),APP_TEMPLATE:i("APP_TEMPLATE"),BUTTON_TAG:i("BUTTON_TAG"),STRIPE_PUBLIC_KEY:i("STRIPE_PUBLIC_KEY"),STRIPE_SOURCE:i("STRIPE_SOURCE"),STRIPE_TRIAL_PERIOD_DAYS:i("STRIPE_TRIAL_PERIOD_DAYS"),SUBSCRIPTION_NEEDED:i("SUBSCRIPTION_NEEDED"),USER_PREFIX:i("USER_PREFIX"),ANONYMOUS_TOKEN:i("ANONYMOUS_TOKEN")})),[]);t((()=>{!l&&a&&(async()=>{try{const o=await m({});console.debug("CODICENT: ACCESS TOKEN",o),d(o)}catch(o){console.debug("CODICENT: Failed to get access token",o);const e=o;if(e&&"object"==typeof e&&"error"in e&&"login_required"===e.error)console.warn("CODICENT: Session expired (login_required)"),d(null);else if(e&&"object"==typeof e&&"error"in e&&"consent_required"===e.error)try{const o=await u();if(!o)return void C("Failed to get access token: no token from auth0 with popup");console.log("CODICENT: GOT ACCESS TOKEN"),d(o)}catch(o){console.warn("CODICENT: Failed to get access token with popup",o),C("Samtycke krävs för inloggning. Tillåt popup-fönster och försök igen."),d(null)}else C("Failed to get access token: "+(e.message?.toString()||e.toString())),console.log("CODICENT: ACCESS TOKEN ERROR",e)}})().then((()=>{}))}),[a,u,m,j,l]),t((()=>{if(c&&c.sub&&E&&void 0===_){let o=!0;return(p?.loginFn?p.loginFn(h,c.sub,E):h.loginUser(c.sub,E)).then((e=>{o&&(null===e?T(!1):""===e?C("Kontrollera internetanslutningen och försök igen."):(h.setToken(e),h.getNickname().then(I),T(!0)))})).catch((()=>{o&&(C("Ett fel uppstod. Försök igen senare."),T(!1))})),()=>{o=!1}}}),[c,E,_,h]);const O=s((()=>{h.logout(),d(null),C(null),T(void 0),I(""),g({logoutParams:{returnTo:i("AUTH_REDIRECT_URL")}})}),[h,g]),R=s((async o=>{const e=p?.registerFn?await p.registerFn(h,o,c.email,c.sub,E):await h.registerUser(o,c.email,c.sub,E);return e&&(h.setToken(e),T(!0)),e}),[h,c,E]);t((()=>{h.onUnauthorized=O}),[h]);const N=s((async o=>{try{await P({authorizationParams:{connection:"email",login_hint:o}})}catch(o){console.error("Passwordless login failed:",o),C(`Passwordless login failed: ${o}`)}}),[P]);return e((()=>({isAuthenticated:a,isRegistered:_,accessToken:E,authError:S,isLoading:l,user:c,nickname:A,logout:O,registerUser:R,codicentService:h,loginWithRedirect:j,loginPasswordless:N})),[a,_,E,S,l,c,A,O,R,h,j,N])};export{r as default};
@@ -1,6 +1,6 @@
1
1
  import { Auth0ContextInterface } from "@auth0/auth0-react";
2
2
  import { CodicentService } from "../services";
3
- import { AppStateMachine, StateContext, AppStateDefinition } from "../utils";
3
+ import AppStateMachine, { StateContext, AppStateDefinition } from "../utils/appState";
4
4
  import { AudioRecorderState } from "./useAudioRecorder";
5
5
  import { AuthStateOptions, UseAuthState } from "./useAuthState";
6
6
  import { RealtimeVoice } from "./useRealtimeVoiceAI";
@@ -1 +1 @@
1
- {"version":3,"file":"useCodicentApp.d.ts","sourceRoot":"","sources":["../../../src/hooks/useCodicentApp.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,kBAAkB,EAAyB,MAAM,UAAU,CAAC;AACpG,OAAyB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAqB,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9E,OAA2B,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACzE,OAAiB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAGnD,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,kBAAkB,CAAC;IAC1B,IAAI,EAAE,YAAY,CAAC;IACnB,YAAY,EAAE,eAAe,CAAC;IAC9B,OAAO,EAAE,eAAe,CAAC;IACzB,OAAO,EAAE,YAAY,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;IACnC,YAAY,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,SAAS,EAAE,kBAAkB,CAAC;IAC9B,MAAM,EAAE,MAAM,OAAO,CAAC;IACtB,KAAK,EAAE,aAAa,GAAG,SAAS,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,qBAAqB,CAAC;IAC7B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,WAAW,CAAC,EAAE,gBAAgB,CAAC;CAChC;AAED,eAAO,MAAM,cAAc,wCAAyC,qBAAqB,KAoMlF,gBACN,CAAC"}
1
+ {"version":3,"file":"useCodicentApp.d.ts","sourceRoot":"","sources":["../../../src/hooks/useCodicentApp.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,eAAe,EAAE,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACtF,OAAyB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAqB,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9E,OAA2B,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACzE,OAAiB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAanD,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,kBAAkB,CAAC;IAC1B,IAAI,EAAE,YAAY,CAAC;IACnB,YAAY,EAAE,eAAe,CAAC;IAC9B,OAAO,EAAE,eAAe,CAAC;IACzB,OAAO,EAAE,YAAY,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;IACnC,YAAY,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,SAAS,EAAE,kBAAkB,CAAC;IAC9B,MAAM,EAAE,MAAM,OAAO,CAAC;IACtB,KAAK,EAAE,aAAa,GAAG,SAAS,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,qBAAqB,CAAC;IAC7B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,WAAW,CAAC,EAAE,gBAAgB,CAAC;CAChC;AAED,eAAO,MAAM,cAAc,wCAAyC,qBAAqB,KA2WlF,gBACN,CAAC"}
@@ -1 +1 @@
1
- import{useRef as e,useState as t,useCallback as r,useMemo as n,useEffect as s}from"react";import"../utils/MessageContent.js";import"../node_modules/tinycolor2/esm/tinycolor.js";import"react/jsx-runtime";import{createAppStateMachine as o}from"../utils/appState.js";import"../_virtual/index.js";import"../lib/wavtools/lib/wav_packer.js";import"../lib/wavtools/lib/analysis/audio_analysis.js";import"../lib/wavtools/lib/wav_stream_player.js";import"../lib/wavtools/lib/wav_recorder.js";import"../utils/cacheManager.js";import{useAudioRecorder as c}from"./useAudioRecorder.js";import a from"./useAuthState.js";import i from"./useRealtimeVoiceAI.js";import u from"./useTools.js";const l=({auth0:l,toolsConfig:m,authOptions:p})=>{const d=a(l,p),h=e(null);h.current||(h.current=o(d.codicentService,(()=>{})));const[g,A]=t((()=>{let e="",t=h.current.getCurrentStateName(),r=0;for(;t!==e&&r<10;)h.current.update(),e=t,t=h.current.getCurrentStateName(),r++;return t})),{service:f,context:k}=h.current,{nickname:v,name:S,error:w,errorType:C,selectedApp:j}=k,y=r(((e,t)=>{const r=e.get("file").name;f.uploadFile(r,e).then((e=>{f.sendMessage(`#transcribe ${""!==t?(t.startsWith("#")?"":"#")+t+" ":""}#file:${e}`).then((()=>{})).catch(console.warn)}))}),[f]),b=c(y),[x,N]=t(),[T,_]=t(),[I,R]=t(!1),M=n((()=>new Audio("./notification.mp3")),[]),O=r((()=>R(!0)),[]),J=u(f,N,_,M,x,O,m),B=i(f,J);s((()=>{I&&(B?.disconnectConversation(),R(!1))}),[I,B]),s((()=>{d.isAuthenticated&&d.user&&d.accessToken&&h.current.updateContext({isAuthenticated:d.isAuthenticated,user:{sub:d.user.sub,email:d.user.email},accessToken:d.accessToken})}),[d.isAuthenticated,d.user,d.accessToken]);const L=e(d.isAuthenticated);s((()=>{const e=!0===L.current,t=!0===d.isAuthenticated;e&&!t&&h.current.logout(),L.current=d.isAuthenticated}),[d.isAuthenticated]),s((()=>h.current.updateContext({nickname:d.nickname})),[d.nickname]),s((()=>{h.current.update();let e,t=h.current.getCurrentStateName();A(h.current.getCurrentStateName()),JSON.stringify(h.current.context);let r="hasAccess"===h.current.getCurrentStateName();const n=s=>setInterval((()=>{const s=h.current.getCurrentStateName();"hasAccess"!==s||r?"hasAccess"!==s&&r&&(console.log("🚨 Left stable state - switching to fast polling (200ms)"),r=!1,clearInterval(e),e=n(200)):(console.log("🎯 Reached stable state - switching to slower polling (1000ms)"),r=!0,clearInterval(e),e=n(1e3));const o=JSON.stringify(h.current.context);h.current.update();const c=JSON.stringify(h.current.context),a=h.current.getCurrentStateName();a===t&&o===c||(A(a),t=a)}),s);return e=n(r?1e3:200),()=>clearInterval(e)}),[]);const U=r((e=>e.replace("{nickname}",v||"unknown").replace("{token}",encodeURIComponent(d.accessToken||"unknown")).replace("{app}",j||"unknown")),[v,d.accessToken,j]),$=r((e=>{h.current.updateContext({isAnonymous:e})}),[]),F=r((()=>h.current.isBusy()),[]);return n((()=>({audio:b,auth:d,currentStateName:g,stateMachine:h.current,service:f,context:k,state:g,nickname:v,name:S,error:w,errorType:C,fixAppUrl:U,setAnonymous:$,allStates:h.current.allStates,isBusy:F,voice:B,html:x,setHtml:N,script:T})),[g,v,S,w,C,x,T,d.isAuthenticated,d.isLoading,b.isRecording,B?.isConnected,U,$,F])};export{l as useCodicentApp};
1
+ import{useReducer as e,useCallback as t,useState as r,useMemo as n,useEffect as s,useRef as a}from"react";import{useAudioRecorder as c}from"./useAudioRecorder.js";import i from"./useAuthState.js";import o from"./useRealtimeVoiceAI.js";import p from"./useTools.js";import{getConfigValue as u}from"../config/index.js";import{stateMachineCacheManager as A}from"../utils/cacheManager.js";import{appStateReducer as E,createInitialState as d,saveSession as m,runBackgroundValidation as l,isBusyPhase as T}from"./useAppState.js";const h=({auth0:h,toolsConfig:S,authOptions:g})=>{const k=i(h,g),y=k.codicentService,[{phase:_,context:I},R]=e(E,null,d),f=t(((e,t)=>{const r=e.get("file").name;y.uploadFile(r,e).then((e=>{y.sendMessage(`#transcribe ${""!==t?(t.startsWith("#")?"":"#")+t+" ":""}#file:${e}`).catch(console.warn)}))}),[y]),C=c(f),[U,O]=r(),[D,N]=r(),[P,L]=r(!1),v=n((()=>new Audio("./notification.mp3")),[]),F=t((()=>L(!0)),[]),w=p(y,O,N,v,U,F,S),x=o(y,w);s((()=>{P&&(x?.disconnectConversation(),L(!1))}),[P,x]),s((()=>{k.isLoading||(k.isAuthenticated&&k.accessToken?R({type:"AUTHENTICATED",accessToken:k.accessToken,user:{sub:k.user?.sub??"",email:k.user?.email??""}}):k.isAuthenticated?k.authError&&R({type:"UPDATE_CONTEXT",updates:{error:k.authError}}):R({type:"NOT_AUTHENTICATED"}))}),[k.isLoading,k.isAuthenticated,k.accessToken,k.authError]),s((()=>{"checkingCodicentAccess"===_&&(void 0===k.isRegistered&&k.authError?R({type:"UPDATE_CONTEXT",updates:{error:k.authError,errorType:"CodicentLoginFailed"}}):void 0!==k.isRegistered&&(!0===k.isRegistered&&k.nickname?R({type:"REGISTERED",nickname:k.nickname}):!1===k.isRegistered&&R({type:"NOT_REGISTERED"})))}),[_,k.isRegistered,k.nickname,k.authError]),s((()=>{if("registering"!==_)return;if(!I.accessToken||!I.user)return;let e=!1;return y.setToken(I.accessToken),y.findUsername().then((async t=>{if(e)return;if(!t)return void R({type:"REGISTER_AUTO_FAIL",error:"Användarnamn kunde inte hittas.",errorType:"NoUsernameFound"});const r=await y.nicknameExists(t);e||(r?R({type:"REGISTER_AUTO_FAIL",error:"Användarnamnet finns redan.",errorType:"UsernameExists"}):(await y.registerUser(t,I.user.email,I.user.sub,I.accessToken),e||(y.setToken(I.accessToken),R({type:"REGISTER_AUTO_SUCCESS",nickname:t}))))})).catch((t=>{e||R({type:"REGISTER_AUTO_FAIL",error:t instanceof Error?t.message:String(t),errorType:"ErrorRegistering"})})),()=>{e=!0}}),[_]),s((()=>{if("loadingUser"!==_||!I.nickname)return;let e=!1;return localStorage.setItem("nickname",I.nickname),y.getUserInfo(I.nickname).then((t=>{e||R({type:"USER_LOADED",name:t?.name||t?.nickname||""})})).catch((()=>{e||R({type:"USER_LOADED",name:""})})),()=>{e=!0}}),[_]),s((()=>{if("checkingPurchase"!==_)return;if(!u("SUBSCRIPTION_NEEDED"))return void R({type:"PURCHASE_VALID"});let e=!1;return y.checkSubscriptionStatus().then((t=>{if(!e){R("active"===t||"trialing"===t?{type:"PURCHASE_VALID"}:{type:"PURCHASE_INVALID"})}})).catch((()=>{e||R({type:"PURCHASE_INVALID"})})),()=>{e=!0}}),[_]),s((()=>{if("gettingApps"!==_)return;let e=!1;return y.getApps().then((t=>{e||R(null!==t?{type:"APPS_LOADED",apps:t}:{type:"APPS_FAILED",error:"Failed to fetch apps."})})).catch((t=>{e||R({type:"APPS_FAILED",error:String(t)})})),()=>{e=!0}}),[_]),s((()=>{if("creatingApp"!==_)return;let e=!1;return y.createApp().then((t=>{e||R(t?{type:"APP_CREATED",appId:t}:{type:"APP_CREATE_FAILED",error:"Misslyckades att skapa din app. Försök igen senare."})})).catch((t=>{e||R({type:"APP_CREATE_FAILED",error:String(t)})})),()=>{e=!0}}),[_]),s((()=>{"hasAccess"===_&&I.selectedApp&&(y.codicent=I.selectedApp,localStorage.setItem("selectedApp",I.selectedApp),I.isFromCache||m(I))}),[_,I.selectedApp]);const M=a(!1);s((()=>{"hasAccess"===_&&I.isFromCache&&I.needsValidation&&k.accessToken&&k.isAuthenticated&&(M.current||(M.current=!0,l(y,I,R)))}),[_,I.isFromCache,I.needsValidation,k.accessToken,k.isAuthenticated]),s((()=>{"needsPurchase"===_&&(window.location.href="./#/purchase")}),[_]),s((()=>{if("anonymous"!==_)return;const e=u("ANONYMOUS_TOKEN"),t=u("ANONYMOUS_CODICENT")||u("APP_NAME")||"";e&&(y.setToken(e),y.codicent=t)}),[_]),s((()=>{"loggingOut"===_&&(u("ENABLE_STATE_CACHE")&&A.clear(),localStorage.removeItem("selectedApp"),localStorage.removeItem("nickname"),localStorage.removeItem("codicent"),sessionStorage.clear(),k.logout())}),[_]);const H=a(I);H.current=I;const j=a({}).current,G=a({}).current,V=n((()=>({service:y,get context(){return H.current},current:"hasAccess"===_?j:G,allStates:{hasAccess:j},setSelectedApp:e=>{R({type:"SET_SELECTED_APP",appId:e})},updateContext:e=>{R({type:"UPDATE_CONTEXT",updates:e})},logout:()=>{R({type:"LOGOUT"})},update:()=>{},isBusy:()=>T(_)})),[_,y]),b=t((e=>e.replace("{nickname}",I.nickname||"unknown").replace("{token}",encodeURIComponent(k.accessToken||"unknown")).replace("{app}",I.selectedApp||"unknown")),[I.nickname,k.accessToken,I.selectedApp]),B=t((e=>{e&&u("ANONYMOUS_TOKEN")&&R({type:"SET_ANONYMOUS"})}),[]),Y=t((()=>T(_)),[_]);return n((()=>({audio:C,auth:k,currentStateName:_,stateMachine:V,service:y,context:I,state:_,nickname:I.nickname||"",name:I.name||"",error:I.error||"",errorType:I.errorType||"",fixAppUrl:b,setAnonymous:B,allStates:V.allStates,isBusy:Y,voice:x,html:U||"",setHtml:O,script:D||""})),[_,I,U,D,k.isAuthenticated,k.isLoading,C.isRecording,x?.isConnected,b,B,Y,V])};export{h as useCodicentApp};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codicent-app-sdk",
3
- "version": "0.4.29",
3
+ "version": "0.5.0",
4
4
  "description": "SDK for building AI-powered applications with Codicent",
5
5
  "type": "module",
6
6
  "main": "dist/cjs/index.js",