@mochabug/adapt-web 1.0.1-rc.16 → 1.0.1-rc.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/README.md +15 -15
- package/dist/esm/AdaptAutomationElement.js +1 -1
- package/dist/esm/cap-adapter.js +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/types/AdaptAutomationElement.d.ts +2 -1
- package/dist/types/core.d.ts +1 -1
- package/dist/types/index.d.ts +3 -1
- package/dist/types/types.d.ts +24 -0
- package/dist/umd/adapt-web.cap.js +1 -1
- package/dist/umd/adapt-web.cap.js.br +0 -0
- package/dist/umd/adapt-web.cap.min.js +1 -1
- package/dist/umd/adapt-web.cap.min.js.br +0 -0
- package/dist/umd/adapt-web.core.js +46 -4
- package/dist/umd/adapt-web.core.js.br +0 -0
- package/dist/umd/adapt-web.core.min.js +3 -3
- package/dist/umd/adapt-web.core.min.js.br +0 -0
- package/dist/umd/adapt-web.js +47 -5
- package/dist/umd/adapt-web.js.br +0 -0
- package/dist/umd/adapt-web.min.js +4 -4
- package/dist/umd/adapt-web.min.js.br +0 -0
- package/package.json +2 -2
package/dist/README.md
CHANGED
|
@@ -6,7 +6,7 @@ Embed Adapt automations in any website.
|
|
|
6
6
|
npm install @mochabug/adapt-web
|
|
7
7
|
```
|
|
8
8
|
|
|
9
|
-
**CDN base:** `https://cdn.mochabug.com/adapt/web/1.0.1-rc.
|
|
9
|
+
**CDN base:** `https://cdn.mochabug.com/adapt/web/1.0.1-rc.18/`
|
|
10
10
|
|
|
11
11
|
| Bundle | File | Includes |
|
|
12
12
|
|--------|------|----------|
|
|
@@ -20,8 +20,8 @@ npm install @mochabug/adapt-web
|
|
|
20
20
|
Bundles merge into a single `MbAdapt` global, so you can combine them. For example, headless + Cap for automations that need proof-of-work but no UI:
|
|
21
21
|
|
|
22
22
|
```html
|
|
23
|
-
<script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.
|
|
24
|
-
<script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.
|
|
23
|
+
<script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.18/adapt-core.min.js"></script>
|
|
24
|
+
<script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.18/adapt-web.cap.min.js"></script>
|
|
25
25
|
<script>
|
|
26
26
|
// MbAdapt has exports from both scripts
|
|
27
27
|
var client = MbAdapt.createAdaptClient(
|
|
@@ -43,12 +43,12 @@ Preload the script and load the stylesheet in `<head>` to eliminate flash of uns
|
|
|
43
43
|
|
|
44
44
|
```html
|
|
45
45
|
<head>
|
|
46
|
-
<link rel="preload" href="https://cdn.mochabug.com/adapt/web/1.0.1-rc.
|
|
47
|
-
<link rel="stylesheet" href="https://cdn.mochabug.com/adapt/web/1.0.1-rc.
|
|
46
|
+
<link rel="preload" href="https://cdn.mochabug.com/adapt/web/1.0.1-rc.18/adapt-web.min.js" as="script">
|
|
47
|
+
<link rel="stylesheet" href="https://cdn.mochabug.com/adapt/web/1.0.1-rc.18/styles.css">
|
|
48
48
|
</head>
|
|
49
49
|
<body>
|
|
50
50
|
<adapt-automation automation-id="YOUR_ID" requires-challenge style="height: 600px"></adapt-automation>
|
|
51
|
-
<script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.
|
|
51
|
+
<script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.18/adapt-web.min.js"></script>
|
|
52
52
|
</body>
|
|
53
53
|
```
|
|
54
54
|
|
|
@@ -56,12 +56,12 @@ No challenges? Use the core bundle and drop `requires-challenge`:
|
|
|
56
56
|
|
|
57
57
|
```html
|
|
58
58
|
<head>
|
|
59
|
-
<link rel="preload" href="https://cdn.mochabug.com/adapt/web/1.0.1-rc.
|
|
60
|
-
<link rel="stylesheet" href="https://cdn.mochabug.com/adapt/web/1.0.1-rc.
|
|
59
|
+
<link rel="preload" href="https://cdn.mochabug.com/adapt/web/1.0.1-rc.18/adapt-web.core.min.js" as="script">
|
|
60
|
+
<link rel="stylesheet" href="https://cdn.mochabug.com/adapt/web/1.0.1-rc.18/styles.css">
|
|
61
61
|
</head>
|
|
62
62
|
<body>
|
|
63
63
|
<adapt-automation automation-id="YOUR_ID" style="height: 600px"></adapt-automation>
|
|
64
|
-
<script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.
|
|
64
|
+
<script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.18/adapt-web.core.min.js"></script>
|
|
65
65
|
</body>
|
|
66
66
|
```
|
|
67
67
|
|
|
@@ -71,14 +71,14 @@ Just the element and script. CSS is auto-injected at runtime.
|
|
|
71
71
|
|
|
72
72
|
```html
|
|
73
73
|
<adapt-automation automation-id="YOUR_ID" requires-challenge style="height: 600px"></adapt-automation>
|
|
74
|
-
<script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.
|
|
74
|
+
<script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.18/adapt-web.min.js"></script>
|
|
75
75
|
```
|
|
76
76
|
|
|
77
77
|
Without challenges:
|
|
78
78
|
|
|
79
79
|
```html
|
|
80
80
|
<adapt-automation automation-id="YOUR_ID" style="height: 600px"></adapt-automation>
|
|
81
|
-
<script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.
|
|
81
|
+
<script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.18/adapt-web.core.min.js"></script>
|
|
82
82
|
```
|
|
83
83
|
|
|
84
84
|
### ESM
|
|
@@ -160,12 +160,12 @@ Requires a `client` JS property — set it after the element is in the DOM.
|
|
|
160
160
|
|
|
161
161
|
```html
|
|
162
162
|
<head>
|
|
163
|
-
<link rel="preload" href="https://cdn.mochabug.com/adapt/web/1.0.1-rc.
|
|
164
|
-
<link rel="stylesheet" href="https://cdn.mochabug.com/adapt/web/1.0.1-rc.
|
|
163
|
+
<link rel="preload" href="https://cdn.mochabug.com/adapt/web/1.0.1-rc.18/adapt-web.cap.min.js" as="script">
|
|
164
|
+
<link rel="stylesheet" href="https://cdn.mochabug.com/adapt/web/1.0.1-rc.18/styles.css">
|
|
165
165
|
</head>
|
|
166
166
|
<body>
|
|
167
167
|
<adapt-cap automation-id="YOUR_ID"></adapt-cap>
|
|
168
|
-
<script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.
|
|
168
|
+
<script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.18/adapt-web.cap.min.js"></script>
|
|
169
169
|
<script>
|
|
170
170
|
var el = document.querySelector('adapt-cap');
|
|
171
171
|
el.client = MbAdapt.createConnectClient({ id: 'YOUR_ID' });
|
|
@@ -180,7 +180,7 @@ Requires a `client` JS property — set it after the element is in the DOM.
|
|
|
180
180
|
|
|
181
181
|
```html
|
|
182
182
|
<adapt-cap automation-id="YOUR_ID"></adapt-cap>
|
|
183
|
-
<script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.
|
|
183
|
+
<script src="https://cdn.mochabug.com/adapt/web/1.0.1-rc.18/adapt-web.cap.min.js"></script>
|
|
184
184
|
<script>
|
|
185
185
|
var el = document.querySelector('adapt-cap');
|
|
186
186
|
el.client = MbAdapt.createConnectClient({ id: 'YOUR_ID' });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{AdaptWebClient}from"./index.js";const OBSERVED_ATTRIBUTES=["automation-id","session-token","auth-token","transmitter","challenge-token","requires-challenge","inherit-token","fork-display-mode","side-by-side-split","dark-mode","auto-resizing","allow-floating","allow-docking","allow-dialog-docking","allow-minimize","allow-maximize","floating-auto-resize","confirm-on-close","persist"],BaseElement=typeof HTMLElement<"u"?HTMLElement:class{};class AdaptAutomationElement extends BaseElement{constructor(){super();this._client=null}static get observedAttributes(){return OBSERVED_ATTRIBUTES}get theme(){return this._theme}set theme(v){this._theme=v,this._client?.setTheme(v)}get automationId(){return this.getAttribute("automation-id")}set automationId(v){v===null?this.removeAttribute("automation-id"):this.setAttribute("automation-id",v)}get darkMode(){return this.hasAttribute("dark-mode")}set darkMode(v){v?this.setAttribute("dark-mode",""):this.removeAttribute("dark-mode")}get autoResizing(){return this.hasAttribute("auto-resizing")}set autoResizing(v){v?this.setAttribute("auto-resizing",""):this.removeAttribute("auto-resizing")}get allowFloating(){return!this.hasAttribute("allow-floating")||this.getAttribute("allow-floating")!=="false"}set allowFloating(v){v?this.removeAttribute("allow-floating"):this.setAttribute("allow-floating","false")}get allowDocking(){return!this.hasAttribute("allow-docking")||this.getAttribute("allow-docking")!=="false"}set allowDocking(v){v?this.removeAttribute("allow-docking"):this.setAttribute("allow-docking","false")}get allowDialogDocking(){return!this.hasAttribute("allow-dialog-docking")||this.getAttribute("allow-dialog-docking")!=="false"}set allowDialogDocking(v){v?this.removeAttribute("allow-dialog-docking"):this.setAttribute("allow-dialog-docking","false")}get allowMinimize(){return!this.hasAttribute("allow-minimize")||this.getAttribute("allow-minimize")!=="false"}set allowMinimize(v){v?this.removeAttribute("allow-minimize"):this.setAttribute("allow-minimize","false")}get allowMaximize(){return!this.hasAttribute("allow-maximize")||this.getAttribute("allow-maximize")!=="false"}set allowMaximize(v){v?this.removeAttribute("allow-maximize"):this.setAttribute("allow-maximize","false")}get floatingAutoResize(){return this.hasAttribute("floating-auto-resize")}set floatingAutoResize(v){v?this.setAttribute("floating-auto-resize",""):this.removeAttribute("floating-auto-resize")}get confirmOnClose(){return this.hasAttribute("confirm-on-close")}set confirmOnClose(v){v?this.setAttribute("confirm-on-close",""):this.removeAttribute("confirm-on-close")}get forkDisplayMode(){return this.getAttribute("fork-display-mode")==="dialog"?"dialog":"side-by-side"}set forkDisplayMode(v){this.setAttribute("fork-display-mode",v)}get persist(){return this.hasAttribute("persist")}set persist(v){v?this.setAttribute("persist",""):this.removeAttribute("persist")}async newSession(){this._client&&await this._client.newSession()}connectedCallback(){queueMicrotask(()=>this._tryInit())}disconnectedCallback(){this._destroyClient()}attributeChangedCallback(name,oldValue,newValue){if(oldValue!==newValue){if(name==="automation-id"||name==="persist"){this._destroyClient(),queueMicrotask(()=>this._tryInit());return}if(this._client)switch(name){case"fork-display-mode":this._client.setForkDisplayMode(this.forkDisplayMode);break;case"dark-mode":this._client.setDarkMode(this.darkMode);break;case"auto-resizing":this._client.setAutoResizing(this.autoResizing);break;case"allow-floating":this._client.setAllowFloating(this.allowFloating);break;case"allow-docking":this._client.setAllowDocking(this.allowDocking);break;case"allow-dialog-docking":this._client.setAllowDialogDocking(this.allowDialogDocking);break;case"allow-minimize":this._client.setAllowMinimize(this.allowMinimize);break;case"allow-maximize":this._client.setAllowMaximize(this.allowMaximize);break;case"floating-auto-resize":this._client.setFloatingAutoResize(this.floatingAutoResize);break;case"confirm-on-close":this._client.setConfirmOnClose(this.confirmOnClose);break}}}_tryInit(){if(this._client||!this.isConnected)return;const automationId=this.automationId;if(!automationId)return;const sessionToken=this.getAttribute("session-token"),authToken=this.getAttribute("auth-token"),transmitter=this.getAttribute("transmitter"),challengeToken=this.getAttribute("challenge-token"),requiresChallenge=this.hasAttribute("requires-challenge"),inheritToken=this.getAttribute("inherit-token"),sideBySideSplitAttr=this.getAttribute("side-by-side-split");let forkDisplay;this.forkDisplayMode==="dialog"?forkDisplay={mode:"dialog"}:forkDisplay={mode:"side-by-side",...sideBySideSplitAttr!==null&&{split:Number(sideBySideSplitAttr)}};const options={container:this,automationId,forkDisplay,darkMode:this.darkMode,autoResizing:this.autoResizing,onSession:(status,fork)=>{this.onSessionCallback?.(status,fork),this.dispatchEvent(new CustomEvent("adapt-session",{detail:{status,fork},bubbles:!0}))},onOutput:output=>{this.onOutputCallback?.(output),this.dispatchEvent(new CustomEvent("adapt-output",{detail:{output},bubbles:!0}))},onForkActive:active=>{this.onForkActiveCallback?.(active),this.dispatchEvent(new CustomEvent("adapt-fork-active",{detail:{active},bubbles:!0}))}};this.allowFloating||(options.allowFloating=!1),this.allowDocking||(options.allowDocking=!1),this.allowDialogDocking||(options.allowDialogDocking=!1),this.allowMinimize||(options.allowMinimize=!1),this.allowMaximize||(options.allowMaximize=!1),this.floatingAutoResize&&(options.floatingAutoResize=!0),this.confirmOnClose&&(options.confirmOnClose=!0),sessionToken&&(options.sessionToken=sessionToken),authToken&&(options.authToken=authToken),transmitter&&(options.transmitter=transmitter),challengeToken&&(options.challengeToken=challengeToken),requiresChallenge&&(options.requiresChallenge=!0),inheritToken&&(options.inheritToken=inheritToken),this.signals!==void 0&&(options.signals=this.signals),this.capWidgetOptions!==void 0&&(options.capWidgetOptions=this.capWidgetOptions),this.inheritFrom!==void 0&&(options.inheritFrom=this.inheritFrom),this.classNames!==void 0&&(options.classNames=this.classNames),this.styles!==void 0&&(options.styles=this.styles),this.text!==void 0&&(options.text=this.text),this._theme!==void 0&&(options.theme=this._theme),this.persistOptions!==void 0?options.persist=this.persistOptions:this.persist&&(options.persist=!0),this._client=new AdaptWebClient(options)}_destroyClient(){this._client&&(this._client.destroy(),this._client=null)}}if(typeof customElements<"u"&&!customElements.get("adapt-automation")){customElements.define("adapt-automation",AdaptAutomationElement);const styleId="adapt-element-display";if(!document.getElementById(styleId)){const s=document.createElement("style");s.id=styleId,s.textContent="adapt-automation, adapt-cap { display: block; }",document.head.appendChild(s)}}export{AdaptAutomationElement};
|
|
1
|
+
import{AdaptWebClient}from"./index.js";const OBSERVED_ATTRIBUTES=["automation-id","session-token","auth-token","transmitter","challenge-token","requires-challenge","inherit-token","fork-display-mode","side-by-side-split","dark-mode","auto-resizing","allow-floating","allow-docking","allow-dialog-docking","allow-minimize","allow-maximize","floating-auto-resize","confirm-on-close","persist"],BaseElement=typeof HTMLElement<"u"?HTMLElement:class{};class AdaptAutomationElement extends BaseElement{constructor(){super();this._client=null}static get observedAttributes(){return OBSERVED_ATTRIBUTES}get theme(){return this._theme}set theme(v){this._theme=v,this._client?.setTheme(v)}get automationId(){return this.getAttribute("automation-id")}set automationId(v){v===null?this.removeAttribute("automation-id"):this.setAttribute("automation-id",v)}get darkMode(){return this.hasAttribute("dark-mode")}set darkMode(v){v?this.setAttribute("dark-mode",""):this.removeAttribute("dark-mode")}get autoResizing(){return this.hasAttribute("auto-resizing")}set autoResizing(v){v?this.setAttribute("auto-resizing",""):this.removeAttribute("auto-resizing")}get allowFloating(){return!this.hasAttribute("allow-floating")||this.getAttribute("allow-floating")!=="false"}set allowFloating(v){v?this.removeAttribute("allow-floating"):this.setAttribute("allow-floating","false")}get allowDocking(){return!this.hasAttribute("allow-docking")||this.getAttribute("allow-docking")!=="false"}set allowDocking(v){v?this.removeAttribute("allow-docking"):this.setAttribute("allow-docking","false")}get allowDialogDocking(){return!this.hasAttribute("allow-dialog-docking")||this.getAttribute("allow-dialog-docking")!=="false"}set allowDialogDocking(v){v?this.removeAttribute("allow-dialog-docking"):this.setAttribute("allow-dialog-docking","false")}get allowMinimize(){return!this.hasAttribute("allow-minimize")||this.getAttribute("allow-minimize")!=="false"}set allowMinimize(v){v?this.removeAttribute("allow-minimize"):this.setAttribute("allow-minimize","false")}get allowMaximize(){return!this.hasAttribute("allow-maximize")||this.getAttribute("allow-maximize")!=="false"}set allowMaximize(v){v?this.removeAttribute("allow-maximize"):this.setAttribute("allow-maximize","false")}get floatingAutoResize(){return this.hasAttribute("floating-auto-resize")}set floatingAutoResize(v){v?this.setAttribute("floating-auto-resize",""):this.removeAttribute("floating-auto-resize")}get confirmOnClose(){return this.hasAttribute("confirm-on-close")}set confirmOnClose(v){v?this.setAttribute("confirm-on-close",""):this.removeAttribute("confirm-on-close")}get forkDisplayMode(){return this.getAttribute("fork-display-mode")==="dialog"?"dialog":"side-by-side"}set forkDisplayMode(v){this.setAttribute("fork-display-mode",v)}get persist(){return this.hasAttribute("persist")}set persist(v){v?this.setAttribute("persist",""):this.removeAttribute("persist")}async newSession(){this._client&&await this._client.newSession()}connectedCallback(){queueMicrotask(()=>this._tryInit())}disconnectedCallback(){this._destroyClient()}attributeChangedCallback(name,oldValue,newValue){if(oldValue!==newValue){if(name==="automation-id"||name==="persist"){this._destroyClient(),queueMicrotask(()=>this._tryInit());return}if(this._client)switch(name){case"fork-display-mode":this._client.setForkDisplayMode(this.forkDisplayMode);break;case"dark-mode":this._client.setDarkMode(this.darkMode);break;case"auto-resizing":this._client.setAutoResizing(this.autoResizing);break;case"allow-floating":this._client.setAllowFloating(this.allowFloating);break;case"allow-docking":this._client.setAllowDocking(this.allowDocking);break;case"allow-dialog-docking":this._client.setAllowDialogDocking(this.allowDialogDocking);break;case"allow-minimize":this._client.setAllowMinimize(this.allowMinimize);break;case"allow-maximize":this._client.setAllowMaximize(this.allowMaximize);break;case"floating-auto-resize":this._client.setFloatingAutoResize(this.floatingAutoResize);break;case"confirm-on-close":this._client.setConfirmOnClose(this.confirmOnClose);break}}}_tryInit(){if(this._client||!this.isConnected)return;const automationId=this.automationId;if(!automationId)return;const sessionToken=this.getAttribute("session-token"),authToken=this.getAttribute("auth-token"),transmitter=this.getAttribute("transmitter"),challengeToken=this.getAttribute("challenge-token"),requiresChallenge=this.hasAttribute("requires-challenge"),inheritToken=this.getAttribute("inherit-token"),sideBySideSplitAttr=this.getAttribute("side-by-side-split");let forkDisplay;this.forkDisplayMode==="dialog"?forkDisplay={mode:"dialog"}:forkDisplay={mode:"side-by-side",...sideBySideSplitAttr!==null&&{split:Number(sideBySideSplitAttr)}};const options={container:this,automationId,forkDisplay,darkMode:this.darkMode,autoResizing:this.autoResizing,onSession:(status,fork)=>{this.onSessionCallback?.(status,fork),this.dispatchEvent(new CustomEvent("adapt-session",{detail:{status,fork},bubbles:!0}))},onOutput:output=>{this.onOutputCallback?.(output),this.dispatchEvent(new CustomEvent("adapt-output",{detail:{output},bubbles:!0}))},onForkActive:active=>{this.onForkActiveCallback?.(active),this.dispatchEvent(new CustomEvent("adapt-fork-active",{detail:{active},bubbles:!0}))},onError:error=>{this.onErrorCallback?.(error),this.dispatchEvent(new CustomEvent("adapt-error",{detail:{error},bubbles:!0}))}};this.allowFloating||(options.allowFloating=!1),this.allowDocking||(options.allowDocking=!1),this.allowDialogDocking||(options.allowDialogDocking=!1),this.allowMinimize||(options.allowMinimize=!1),this.allowMaximize||(options.allowMaximize=!1),this.floatingAutoResize&&(options.floatingAutoResize=!0),this.confirmOnClose&&(options.confirmOnClose=!0),sessionToken&&(options.sessionToken=sessionToken),authToken&&(options.authToken=authToken),transmitter&&(options.transmitter=transmitter),challengeToken&&(options.challengeToken=challengeToken),requiresChallenge&&(options.requiresChallenge=!0),inheritToken&&(options.inheritToken=inheritToken),this.signals!==void 0&&(options.signals=this.signals),this.capWidgetOptions!==void 0&&(options.capWidgetOptions=this.capWidgetOptions),this.inheritFrom!==void 0&&(options.inheritFrom=this.inheritFrom),this.classNames!==void 0&&(options.classNames=this.classNames),this.styles!==void 0&&(options.styles=this.styles),this.text!==void 0&&(options.text=this.text),this._theme!==void 0&&(options.theme=this._theme),this.persistOptions!==void 0?options.persist=this.persistOptions:this.persist&&(options.persist=!0),this._client=new AdaptWebClient(options)}_destroyClient(){this._client&&(this._client.destroy(),this._client=null)}}if(typeof customElements<"u"&&!customElements.get("adapt-automation")){customElements.define("adapt-automation",AdaptAutomationElement);const styleId="adapt-element-display";if(!document.getElementById(styleId)){const s=document.createElement("style");s.id=styleId,s.textContent="adapt-automation, adapt-cap { display: block; }",document.head.appendChild(s)}}export{AdaptAutomationElement};
|
package/dist/esm/cap-adapter.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
typeof window<"u"&&!window.CAP_CUSTOM_WASM_URL&&(window.CAP_CUSTOM_WASM_URL=new URL("https://cdn.mochabug.com/adapt/web/1.0.1-rc.
|
|
1
|
+
typeof window<"u"&&!window.CAP_CUSTOM_WASM_URL&&(window.CAP_CUSTOM_WASM_URL=new URL("https://cdn.mochabug.com/adapt/web/1.0.1-rc.18/cap_wasm.js",window.location.href).href);import{timestampDate}from"@bufbuild/protobuf/wkt";let currentClient=null,currentAutomationId=null;const verificationTokens=new Map;async function createChallenge(client,id){const response=await client.createChallenge({id});return{count:response.count,size:response.size,difficulty:response.difficulty,expires:response.expires?timestampDate(response.expires):new Date,token:response.token,verificationToken:response.verificationToken}}async function redeemChallenge(client,id,verificationToken,solutions){const response=await client.redeemChallenge({id,verificationToken,solutions});return{token:response.token,expires:response.expires?timestampDate(response.expires):new Date}}typeof window<"u"&&(window.CAP_CUSTOM_FETCH=async(url,options)=>{const urlStr=url.toString();if(urlStr.endsWith("/challenge")){if(!currentClient||!currentAutomationId)return new Response(JSON.stringify({error:"Cap adapter not initialized"}),{status:500,headers:{"Content-Type":"application/json"}});try{const challengeInfo=await createChallenge(currentClient,currentAutomationId);return verificationTokens.set(currentAutomationId,challengeInfo.verificationToken),new Response(JSON.stringify({challenge:{c:challengeInfo.count,s:challengeInfo.size,d:challengeInfo.difficulty},token:challengeInfo.token,expires:challengeInfo.expires.toISOString()}),{status:200,headers:{"Content-Type":"application/json"}})}catch(error){return new Response(JSON.stringify({error:String(error)}),{status:500,headers:{"Content-Type":"application/json"}})}}if(urlStr.endsWith("/redeem")){if(!currentClient||!currentAutomationId)return new Response(JSON.stringify({error:"Cap adapter not initialized"}),{status:500,headers:{"Content-Type":"application/json"}});const verificationToken=verificationTokens.get(currentAutomationId);if(!verificationToken)return new Response(JSON.stringify({error:"No verification token found - challenge must be created first"}),{status:400,headers:{"Content-Type":"application/json"}});try{const solutions=((options?.body?JSON.parse(options.body):{}).solutions||[]).map(s=>BigInt(s)),redeemed=await redeemChallenge(currentClient,currentAutomationId,verificationToken,solutions);return verificationTokens.delete(currentAutomationId),new Response(JSON.stringify({success:!0,token:redeemed.token,expires:redeemed.expires.toISOString()}),{status:200,headers:{"Content-Type":"application/json"}})}catch(error){return new Response(JSON.stringify({error:String(error)}),{status:500,headers:{"Content-Type":"application/json"}})}}return fetch(url,options)});function setupCapAdapter(client,automationId){currentClient=client,currentAutomationId=automationId}function cleanupCapAdapter(){currentAutomationId&&verificationTokens.delete(currentAutomationId),currentClient=null,currentAutomationId=null}export{cleanupCapAdapter,createChallenge,redeemChallenge,setupCapAdapter};
|
package/dist/esm/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Code,configure,ConnectError,createAdaptClient,resetConfig}from"@mochabug/adapt-core";import{createConnectClient}from"@mochabug/adapt-core/connect";import{PanelManager}from"./panel-manager.js";import{FloatingToolbar,ForkGroupActions,IframePanelComponent,injectPanelManagerStyles,MinimizeManager}from"./panel-setup.js";import{resolveTheme}from"./theme.js";import{resolveTheme as resolveTheme2}from"./theme.js";import{AdaptAutomationElement}from"./AdaptAutomationElement.js";import{FloatingToolbar as FloatingToolbar2,ForkGroupActions as ForkGroupActions2,IframePanelComponent as IframePanelComponent2,MinimizeManager as MinimizeManager2}from"./panel-setup.js";import{PanelManager as PanelManager2}from"./panel-manager.js";function clearPersistedState(automationId,storage="both",persistKey){const key=`mb_adapt_${persistKey??automationId}`;(storage==="session"||storage==="both")&&sessionStorage.removeItem(key),(storage==="local"||storage==="both")&&localStorage.removeItem(key)}const MAIN_PANEL_ID="main",FORK_GROUP_ID="fork-group",DEFAULT_RESPONSIVE_BREAKPOINT=768,DEFAULT_RESPONSIVE_HYSTERESIS=40,_AdaptWebClient=class _AdaptWebClient{constructor(options){this.rootElement=null;this.panelManager=null;this.mainUrl=null;this.sessionToken=null;this.forks=new Map;this.mainRetentionPolicy="retain";this.mainCloseTimer=null;this.components=new Map;this.floatingAutoResized=new Set;this.beforeUnloadHandler=null;this.resizeObserver=null;this._autoMaximizedByResize=!1;this.destroyed=!1;this.removingPanelProgrammatically=!1;this.lastForkActive=null;this.messageHandler=null;this.minimizedTabsContainer=null;this.lastReportedContentHeight=0;this.forkPanelHeights=new Map;this.statusMessageElement=null;this.capWidgetInstance=null;this.minimizeManager=null;this.forkGroupActions=new Map;this.floatingToolbars=new Map;this.options=options;const fd=options.forkDisplay??{mode:"side-by-side"};this.forkDisplay=fd,this.darkMode=options.darkMode??!1,this.autoResizing=options.autoResizing??!1,this.allowFloating=options.allowFloating??!0,this.allowDocking=options.allowDocking??!0,this.allowDialogDocking=options.allowDialogDocking??!0,this.allowMinimize=options.allowMinimize??!0,this.allowMaximize=options.allowMaximize??!0,this.floatingAutoResize=options.floatingAutoResize??!1,this.confirmOnClose=options.confirmOnClose??!1,this.theme=options.theme;const container=typeof options.container=="string"?document.getElementById(options.container):options.container;if(!container)throw new Error(`Container with id '${options.container}' not found`);this.container=container;const rawClient=createConnectClient({id:options.automationId});this.client=createAdaptClient(rawClient,options.automationId),injectPanelManagerStyles(),this.createRootElement(),this.createPanelManager(),this.wireBeforeTabClose(),this.setupMessageListener(),this.init().catch(error=>{this.showErrorStatus(error)})}static registerCapWidget(cls){_AdaptWebClient._capWidgetClass=cls}get responsiveBreakpoint(){if(!this.rootElement)return DEFAULT_RESPONSIVE_BREAKPOINT;const v=getComputedStyle(this.rootElement).getPropertyValue("--mb-adapt-responsive-breakpoint").trim(),n=Number(v);return n>0?n:DEFAULT_RESPONSIVE_BREAKPOINT}get responsiveHysteresis(){if(!this.rootElement)return DEFAULT_RESPONSIVE_HYSTERESIS;const v=getComputedStyle(this.rootElement).getPropertyValue("--mb-adapt-responsive-hysteresis").trim(),n=Number(v);return n>=0?n:DEFAULT_RESPONSIVE_HYSTERESIS}onComponentCreated(panelId,component){this.components.set(panelId,component)}onComponentDisposed(panelId){this.components.delete(panelId)}getDarkMode(){return this.darkMode}getClassNames(){return this.options.classNames}createPanelManager(){if(!this.rootElement)return;this.minimizeManager=new MinimizeManager,this.minimizeManager.setAllowDocking(this.allowDocking),this.minimizedTabsContainer=document.createElement("div"),this.minimizedTabsContainer.className="mb-adapt-minimized-tabs",this.rootElement.appendChild(this.minimizedTabsContainer),this.panelManager=new PanelManager({container:this.rootElement,onGroupCreatedByDrag:group=>{group.dragConstraint="merge-only",this.allowDocking||(group.dockingBlocked=!0),this.allowDialogDocking||(group.dialogDockingBlocked=!0),this.setupForkGroupActions(group)}});const mainGroup=this.panelManager.addGroup({id:"main-group"});this.panelManager.setMainGroup(mainGroup),mainGroup.locked="no-drop-target",mainGroup.setHeaderHidden(!0),mainGroup.element.setAttribute("data-main-group","true");const mainComponent=new IframePanelComponent(this);mainComponent.init(MAIN_PANEL_ID,{}),this.panelManager.addPanel({id:MAIN_PANEL_ID,element:mainComponent.element,groupId:mainGroup.id}),this.minimizeManager.init(this.minimizedTabsContainer,this.panelManager),this.minimizeManager.onBarVisibilityChanged(()=>{this.reapplyAutoResizeHeight()}),this.resizeObserver=new ResizeObserver(entries=>{const cr=entries[0]?.contentRect;cr&&this.onContainerResize(cr.width,cr.height)}),this.resizeObserver.observe(this.rootElement)}getOrigin(url){try{return new URL(url).origin}catch{return null}}isValidMessageOrigin(origin){if(this.mainUrl){const mainOrigin=this.getOrigin(this.mainUrl);if(mainOrigin&&origin===mainOrigin)return!0}for(const fork of this.forks.values()){const forkOrigin=this.getOrigin(fork.url);if(forkOrigin&&origin===forkOrigin)return!0}return!1}findComponentBySource(source){for(const[panelId,component]of this.components)if(component.contentWindow===source)return{panelId,component};return null}setupMessageListener(){this.messageHandler=event=>{if(!this.isValidMessageOrigin(event.origin))return;const data=event.data;if(!data||typeof data!="object")return;const source=event.source,found=this.findComponentBySource(source);if(!found)return;const{panelId,component}=found,isMainPanel=panelId===MAIN_PANEL_ID;if(data.type==="adapt-init"&&typeof data.resize=="boolean"){component.resizeCapable=data.resize,isMainPanel&&!data.resize&&this.rootElement&&(this.rootElement.style.height="");const targetOrigin=component.getOrigin();if(targetOrigin){let effective;if(isMainPanel)effective=this.autoResizing&&data.resize;else{const group=this.panelManager?.getPanel(panelId)?.group,inFloating=group?!!this.panelManager?.findOverlayContaining(group.id):!1;effective=data.resize&&(inFloating&&this.floatingAutoResize||!inFloating&&this.autoResizing)}component.postMessage({type:"adapt-autoResizing",autoResizing:effective},targetOrigin),component.postMessage({type:"adapt-darkMode",darkMode:this.darkMode},targetOrigin)}return}if(data.type==="adapt-resize"){const{height}=data;if(typeof height!="number"||!Number.isFinite(height)||height<1)return;if(isMainPanel)this.lastReportedContentHeight=height,component.resizeCapable&&this.autoResizing&&this.rootElement&&this.applyBestAutoResizeHeight();else{this.forkPanelHeights.set(panelId,height);const group=this.panelManager?.getPanel(panelId)?.group;if(group&&group.activePanel?.id===panelId){const inFloating=!!this.panelManager?.findOverlayContaining(group.id);!inFloating&&component.resizeCapable&&this.autoResizing&&this.rootElement&&this.applyBestAutoResizeHeight(),inFloating&&this.floatingAutoResize&&(this.floatingAutoResized.has(group.id)||(this.floatingAutoResized.add(group.id),this.resizeOverlayForGroup(group)))}}return}},window.addEventListener("message",this.messageHandler)}postToComponent(component,message){const origin=component.getOrigin();origin&&component.postMessage(message,origin)}setDarkMode(darkMode){if(this.darkMode===darkMode)return;this.darkMode=darkMode,this.rootElement?.classList.toggle("mb-adapt--dark",darkMode),this.capWidgetInstance?.setDarkMode(darkMode),this.applyTheme();const msg={type:"adapt-darkMode",darkMode};for(const c of this.components.values())this.postToComponent(c,msg)}setTheme(theme){if(this.theme=theme,this.clearThemeVars(),theme?.mode!==void 0){const dark=theme.mode==="dark";if(this.darkMode!==dark){this.setDarkMode(dark);return}}this.applyTheme()}clearThemeVars(){if(!(!this.rootElement||!this._appliedThemeVars)){for(const key of this._appliedThemeVars)this.rootElement.style.removeProperty(key);this._appliedThemeVars=void 0}}applyTheme(){if(!this.rootElement||!this.theme)return;const vars=resolveTheme(this.theme);for(const[key,value]of Object.entries(vars))this.rootElement.style.setProperty(key,value);this._appliedThemeVars=Object.keys(vars)}setAutoResizing(autoResizing){if(this.autoResizing===autoResizing)return;this.autoResizing=autoResizing;const mainComponent=this.components.get(MAIN_PANEL_ID);mainComponent?.resizeCapable&&this.postToComponent(mainComponent,{type:"adapt-autoResizing",autoResizing});for(const[panelId,component]of this.components){if(panelId===MAIN_PANEL_ID||!component.resizeCapable)continue;const group=this.panelManager?.getPanel(panelId)?.group;group&&this.panelManager?.findOverlayContaining(group.id)||this.postToComponent(component,{type:"adapt-autoResizing",autoResizing})}!autoResizing&&this.rootElement&&(this.rootElement.style.height="")}setAllowFloating(allow){if(this.allowFloating!==allow){this.allowFloating=allow;for(const actions of this.forkGroupActions.values())actions.setAllowFloating(allow)}}setAllowDocking(allow){if(this.allowDocking!==allow){if(this.allowDocking=allow,this.minimizeManager?.setAllowDocking(allow),this.panelManager)for(const group of this.getAllForkGroups())group.dockingBlocked=!allow;for(const toolbar of this.floatingToolbars.values())toolbar.setAllowDocking(allow)}}setAllowDialogDocking(allow){if(this.allowDialogDocking!==allow&&(this.allowDialogDocking=allow,this.panelManager))for(const group of this.getAllForkGroups())group.dialogDockingBlocked=!allow}setAllowMinimize(allow){if(this.allowMinimize!==allow){this.allowMinimize=allow;for(const actions of this.forkGroupActions.values())actions.setAllowMinimize(allow);for(const toolbar of this.floatingToolbars.values())toolbar.setAllowMinimize(allow)}}setAllowMaximize(allow){if(this.allowMaximize!==allow){this.allowMaximize=allow;for(const actions of this.forkGroupActions.values())actions.setAllowMaximize(allow);for(const toolbar of this.floatingToolbars.values())toolbar.setAllowMaximize(allow)}}setFloatingAutoResize(enabled){if(this.floatingAutoResize!==enabled){this.floatingAutoResize=enabled,this.floatingAutoResized.clear();for(const[panelId,component]of this.components){if(panelId===MAIN_PANEL_ID||!component.resizeCapable)continue;const group=this.panelManager?.getPanel(panelId)?.group,effective=(group?!!this.panelManager?.findOverlayContaining(group.id):!1)?enabled&&component.resizeCapable:this.autoResizing&&component.resizeCapable;this.postToComponent(component,{type:"adapt-autoResizing",autoResizing:effective})}}}getAllForkGroups(){if(!this.panelManager)return[];const seen=new Set,groups=[],add=g=>{g.id==="main-group"||seen.has(g.id)||(seen.add(g.id),groups.push(g))},forkGroup=this.panelManager.getGroup(FORK_GROUP_ID);forkGroup&&add(forkGroup);for(const g of this.panelManager.getDockedGroups())add(g);for(const[,overlay]of this.panelManager.getFloatingOverlays())for(const g of overlay.getAllGroups())add(g);return groups}applyAutoResizeHeight(contentHeight){if(!this.rootElement)return;const chrome=this.minimizedTabsContainer?.offsetHeight??0;this.rootElement.style.height=`${Math.ceil(contentHeight)+chrome}px`}applyBestAutoResizeHeight(){if(!this.autoResizing||!this.rootElement)return;let maxHeight=0;if(this.components.get(MAIN_PANEL_ID)?.resizeCapable&&this.lastReportedContentHeight>0){const mainGroup=this.panelManager?.getMainGroup();if(mainGroup?mainGroup.element.offsetHeight>0:!0){const headerH=mainGroup?.headerElement?.offsetHeight??0;maxHeight=this.lastReportedContentHeight+headerH}}for(const group of this.getAllForkGroups()){if(this.panelManager?.findOverlayContaining(group.id)||group.element.offsetHeight<=0)continue;const active=group.activePanel;if(active){const h=this.forkPanelHeights.get(active.id)??0,headerH=group.headerElement?.offsetHeight??0,total=h+headerH;total>maxHeight&&(maxHeight=total)}}maxHeight>0&&this.applyAutoResizeHeight(maxHeight)}reapplyAutoResizeHeight(){this.applyBestAutoResizeHeight()}setForkDisplayMode(mode){this.forkDisplay.mode!==mode&&(mode==="side-by-side"?this.forkDisplay={mode:"side-by-side"}:this.forkDisplay={mode:"dialog"},this.forks.size>0&&this.panelManager&&this.rebuildForkGroup(),this.emitForkActive(),this.saveState())}createRootElement(){this.rootElement=document.createElement("div"),this.rootElement.className=this.options.classNames?.root||"mb-adapt",this.darkMode&&this.rootElement.classList.add("mb-adapt--dark"),this.options.styles&&Object.assign(this.rootElement.style,this.options.styles),this.applyTheme(),this.container.appendChild(this.rootElement)}onUrl(msg){if(this.destroyed)return;const fork=msg.fork||"";if(msg.stopped){this.handleStoppedMessage(fork),this.saveState();return}if(msg.done){this.handleDoneMessage(fork,msg.retentionPolicy),this.saveState();return}msg.url&&(fork?this.handleForkUrl(msg.url,msg.token,fork,msg.source,msg.retentionPolicy):this.handleMainUrl(msg.url,msg.token,msg.source,msg.retentionPolicy),this.saveState())}handleMainUrl(url,token,_source,retentionPolicy){this.mainCloseTimer&&(clearTimeout(this.mainCloseTimer),this.mainCloseTimer=null);const wasMainEmpty=!this.mainUrl;if(this.removeStatusMessage(),this.mainUrl=url,this.mainToken=token,this.mainRetentionPolicy=this.resolveRetention(retentionPolicy),this.panelManager?.isMainGroupCollapsed()&&this.panelManager.expandMainGroup(),wasMainEmpty){const maximizedGroupId=this.getMaximizedDockedGroupId();if(maximizedGroupId){const actions=this.forkGroupActions.get(maximizedGroupId);actions&&actions.clearMaximized()}}const mainComponent=this.components.get(MAIN_PANEL_ID);mainComponent&&(mainComponent.update({url,token}),mainComponent.show())}handleForkUrl(url,token,fork,source,retentionPolicy){if(!this.panelManager)return;const resolved=this.resolveRetention(retentionPolicy),existing=this.forks.get(fork);if(existing){existing.closeTimer&&(clearTimeout(existing.closeTimer),existing.closeTimer=null),existing.url=url,existing.token=token,existing.source=source,existing.retentionPolicy=resolved,existing.completed=!1,existing.recyclable=!1;const component2=this.components.get(existing.panelId);component2&&component2.update({url,token});return}const recyclable=this.findRecyclablePanel(source);if(recyclable){const{forkKey:oldFork,state:rState}=recyclable;rState.closeTimer&&(clearTimeout(rState.closeTimer),rState.closeTimer=null),this.forks.delete(oldFork),rState.url=url,rState.token=token,rState.fork=fork,rState.source=source,rState.retentionPolicy=resolved,rState.completed=!1,rState.recyclable=!1,this.forks.set(fork,rState);const component2=this.components.get(rState.panelId);component2&&component2.update({url,token});return}const panelId=`fork-${fork}`;this.ensureForkGroup(),!this.mainUrl&&this.panelManager&&!this.panelManager.isMainGroupCollapsed()&&this.panelManager.collapseMainGroup();const component=new IframePanelComponent(this);component.init(panelId,{url,token}),this.panelManager.addPanel({id:panelId,element:component.element,groupId:FORK_GROUP_ID}),this.forks.set(fork,{panelId,url,token,fork,source,completed:!1,recyclable:!1,retentionPolicy:resolved,closeTimer:null}),this.emitForkActive()}ensureForkGroup(){if(!this.panelManager||this.panelManager.getGroup(FORK_GROUP_ID))return;const cw=this.rootElement?.offsetWidth??800,ch=this.rootElement?.offsetHeight??600;if(this.forkDisplay.mode==="dialog"){const isSmall=cw<this.responsiveBreakpoint,vw=window.innerWidth,vh=window.innerHeight,fw=isSmall?Math.min(cw*.95,Math.max(200,vw-20)):Math.min(720,cw*.9),fh=isSmall?Math.min(ch*.9,Math.max(200,vh-20)):Math.min(ch*.8,600),group=this.panelManager.addGroup({id:FORK_GROUP_ID,floating:{width:fw,height:fh,x:Math.max(0,(vw-fw)/2),y:Math.max(0,(vh-fh)/2)}});group.dragConstraint="merge-only",this.allowDocking||(group.dockingBlocked=!0),this.allowDialogDocking||(group.dialogDockingBlocked=!0),this.setupForkGroupActions(group),isSmall&&(this.panelManager.getFloatingOverlay(FORK_GROUP_ID)?.maximize(),this._autoMaximizedByResize=!0)}else{const split=this.forkDisplay.mode==="side-by-side"?this.forkDisplay.split:void 0,initialWidth=split!==void 0?cw*(1-split/100):void 0,group=this.panelManager.addGroup({id:FORK_GROUP_ID,direction:"right",initialSize:initialWidth});if(group.dragConstraint="merge-only",this.allowDocking||(group.dockingBlocked=!0),this.allowDialogDocking||(group.dialogDockingBlocked=!0),this.setupForkGroupActions(group),cw<this.responsiveBreakpoint){const fa=this.forkGroupActions.get(group.id);fa?(fa.setMaximized(),fa.setAutoMaximizedByResize(!0)):this.panelManager.maximizeDockedGroup(group),this._autoMaximizedByResize=!0}}}setupForkGroupActions(group){if(!this.panelManager||!this.minimizeManager)return;const actions=new ForkGroupActions(group,this.minimizeManager,this.panelManager,()=>{if(this.setupFloatingToolbar(group),group.location==="grid"&&!this.mainUrl&&this.panelManager&&!this.panelManager.isMainGroupCollapsed()&&this.panelManager.collapseMainGroup(),group.location==="floating"&&this.floatingAutoResized.delete(group.id),this.updateAutoResizeForGroup(group),group.location==="grid"){const currentWidth=this.rootElement?.offsetWidth??0;if(currentWidth>0&¤tWidth<this.responsiveBreakpoint){const fa=this.forkGroupActions.get(group.id);fa&&!fa.isMaximized&&(fa.setMaximized(),this._autoMaximizedByResize=!0,fa.setAutoMaximizedByResize(!0))}}},{allowFloating:this.allowFloating,allowMinimize:this.allowMinimize,allowMaximize:this.allowMaximize});actions.setBeforeClose(()=>this.confirmCloseGroup(group)),actions.onMaximizeChanged(maximized=>{maximized||(this._autoMaximizedByResize=!1,actions.setAutoMaximizedByResize(!1))}),group.setHeaderActions(actions.element),this.forkGroupActions.set(group.id,actions),group.onActivePanelChanged(()=>{this.autoResizing&&this.rootElement&&this.applyBestAutoResizeHeight()}),this.setupFloatingToolbar(group)}updateAutoResizeForGroup(group){const inFloating=this.panelManager?!!this.panelManager.findOverlayContaining(group.id):!1;for(const panel of group.panels){const component=this.components.get(panel.id);if(!component?.resizeCapable)continue;const effective=inFloating?this.floatingAutoResize:this.autoResizing;this.postToComponent(component,{type:"adapt-autoResizing",autoResizing:effective})}}setupFloatingToolbar(group){if(!this.panelManager||!this.minimizeManager)return;const overlay=this.panelManager.findOverlayContaining(group.id);if(overlay)if(group.onPanelCountChanged(()=>overlay.updateTotalTabCount()),overlay.hasToolbar)overlay.repositionToolbar();else{const toolbar=new FloatingToolbar(overlay,this.panelManager,this.minimizeManager,{allowDocking:this.allowDocking,allowMinimize:this.allowMinimize,allowMaximize:this.allowMaximize});toolbar.setBeforeClose(()=>this.confirmCloseGroup(overlay.group)),overlay.setToolbar(toolbar.element),this.floatingToolbars.set(overlay.group.id,toolbar),overlay.updateTotalTabCount()}}resolveRetention(policy){return policy?policy.case:"retain"}findRecyclablePanel(source){let anyRecyclable=null;for(const[forkKey,state]of this.forks)if(state.recyclable){if(source&&state.source===source)return{forkKey,state};anyRecyclable||(anyRecyclable={forkKey,state})}return anyRecyclable}handleMainDone(retentionPolicy){switch(retentionPolicy?this.resolveRetention(retentionPolicy):this.mainRetentionPolicy){case"close":this.scheduleMainClose(retentionPolicy?.case==="close"?retentionPolicy.timeoutSeconds:void 0);break;case"recycle":break;default:break}}scheduleForkClose(fork,state,timeoutSeconds){const doClose=()=>{state.closeTimer=null,this.removingPanelProgrammatically=!0;try{if(this.panelManager){const component=this.components.get(state.panelId);component&&component.dispose(),this.panelManager.removePanel(state.panelId)}this.forks.delete(fork),this.removeForkGroupIfEmpty()}finally{this.removingPanelProgrammatically=!1}this.emitForkActive(),this.saveState()};timeoutSeconds&&timeoutSeconds>0?state.closeTimer=setTimeout(doClose,timeoutSeconds*1e3):doClose()}scheduleMainClose(timeoutSeconds){const doClose=()=>{this.mainCloseTimer=null,this.mainUrl=null,this.mainToken=void 0;const mainComponent=this.components.get(MAIN_PANEL_ID);mainComponent&&mainComponent.hide(),this.panelManager&&!this.panelManager.isMainGroupCollapsed()&&this.panelManager.collapseMainGroup(),this.saveState()};timeoutSeconds&&timeoutSeconds>0?this.mainCloseTimer=setTimeout(doClose,timeoutSeconds*1e3):doClose()}restoreFork(pf){if(!this.panelManager)return;const panelId=`fork-${pf.fork}`;this.ensureForkGroup(),!this.mainUrl&&this.panelManager&&!this.panelManager.isMainGroupCollapsed()&&this.panelManager.collapseMainGroup();const component=new IframePanelComponent(this);component.init(panelId,{url:pf.url,token:pf.token}),this.panelManager.addPanel({id:panelId,element:component.element,groupId:FORK_GROUP_ID}),this.forks.set(pf.fork,{panelId,url:pf.url,token:pf.token,fork:pf.fork,source:pf.source,completed:!1,recyclable:pf.retentionPolicy==="recycle",retentionPolicy:pf.retentionPolicy,closeTimer:null}),this.emitForkActive()}clearAllForks(){this.removingPanelProgrammatically=!0;try{if(this.panelManager)for(const state of this.forks.values()){state.closeTimer&&(clearTimeout(state.closeTimer),state.closeTimer=null);const component=this.components.get(state.panelId);component&&component.dispose(),this.panelManager.removePanel(state.panelId)}this.forks.clear(),this.removeForkGroupIfEmpty()}finally{this.removingPanelProgrammatically=!1}}rebuildForkGroup(){if(!this.panelManager)return;const group=this.panelManager.getGroup(FORK_GROUP_ID);if(group)if(this.forkDisplay.mode==="dialog"){const cw=this.rootElement?.offsetWidth??800,ch=this.rootElement?.offsetHeight??600,fw=Math.min(720,cw*.9),fh=Math.min(ch*.8,600);this.panelManager.addFloatingGroup(group,{width:fw,height:fh,x:(window.innerWidth-fw)/2,y:(window.innerHeight-fh)/2}),this.setupFloatingToolbar(group)}else{const split=this.forkDisplay.mode==="side-by-side"?this.forkDisplay.split:void 0,initialWidth=split!==void 0?(this.rootElement?.offsetWidth??800)*(1-split/100):void 0;this.panelManager.dockGroup(FORK_GROUP_ID,"right",initialWidth)}}handleSessionComplete(){this.clearAllForks(),this.emitForkActive()}handleDoneMessage(fork,retentionPolicy){if(!fork){this.handleMainDone(retentionPolicy);return}const state=this.forks.get(fork);if(!state)return;switch(retentionPolicy?this.resolveRetention(retentionPolicy):state.retentionPolicy){case"close":state.completed=!0,this.scheduleForkClose(fork,state,retentionPolicy?.case==="close"?retentionPolicy.timeoutSeconds:void 0);break;case"recycle":state.completed=!0,state.recyclable=!0;break;default:state.completed=!0;break}}handleStoppedMessage(fork){if(!fork){this.mainCloseTimer&&(clearTimeout(this.mainCloseTimer),this.mainCloseTimer=null),this.mainUrl=null,this.mainToken=void 0;const mainComponent=this.components.get(MAIN_PANEL_ID);mainComponent&&mainComponent.hide(),this.showStatusMessage(this.options.text?.stopped??"This session has been stopped","stopped");return}const state=this.forks.get(fork);if(state){state.closeTimer&&(clearTimeout(state.closeTimer),state.closeTimer=null),this.removingPanelProgrammatically=!0;try{if(this.panelManager){const component=this.components.get(state.panelId);component&&component.dispose(),this.panelManager.removePanel(state.panelId)}this.forks.delete(fork),this.removeForkGroupIfEmpty()}finally{this.removingPanelProgrammatically=!1}this.emitForkActive()}}removeForkGroupIfEmpty(){if(!this.panelManager)return;const g=this.panelManager.getGroup(FORK_GROUP_ID);g&&g.size===0&&(this.panelManager.removeGroup(FORK_GROUP_ID),this._autoMaximizedByResize=!1,this.forkGroupActions.delete(FORK_GROUP_ID),this.floatingToolbars.delete(FORK_GROUP_ID),this.floatingAutoResized.delete(FORK_GROUP_ID)),this.minimizeManager?.removeGroup(FORK_GROUP_ID)}getMaximizedDockedGroupId(){for(const[groupId,actions]of this.forkGroupActions)if(actions.isMaximized)return groupId}emitForkActive(){if(!this.options.onForkActive)return;const active=this.forks.size>0;active!==this.lastForkActive&&(this.lastForkActive=active,this.options.onForkActive(active))}parseInheritToken(){const inheritFrom=this.options.inheritFrom;return inheritFrom?"hash"in inheritFrom?this.parseFromHash(inheritFrom.hash):this.parseFromParam(inheritFrom.param):null}parseFromHash(key){const hash=window.location.hash.slice(1);if(!hash)return null;const params=new URLSearchParams(hash),token=params.get(key);if(!token)return null;params.delete(key);const newHash=params.toString(),newUrl=window.location.pathname+window.location.search+(newHash?"#"+newHash:"");return history.replaceState(null,"",newUrl),decodeURIComponent(token)}parseFromParam(key){const params=new URLSearchParams(window.location.search),token=params.get(key);if(!token)return null;params.delete(key);const newSearch=params.toString(),newUrl=window.location.pathname+(newSearch?"?"+newSearch:"")+window.location.hash;return history.replaceState(null,"",newUrl),decodeURIComponent(token)}async init(){this.panelManager?.onDidRemovePanel(panel=>{if(!this.removingPanelProgrammatically){for(const[fork,state]of this.forks)if(state.panelId===panel.id){state.closeTimer&&(clearTimeout(state.closeTimer),state.closeTimer=null);const component=this.components.get(state.panelId);component&&component.dispose(),this.sessionToken&&this.client.stop(this.sessionToken,fork).catch(()=>{}),this.forks.delete(fork);break}this.emitForkActive()}});const handlers={onUrl:msg=>this.onUrl(msg),onSession:sessionJson=>{sessionJson.status==="STATUS_COMPLETED"&&!sessionJson.fork&&this.handleSessionComplete(),!sessionJson.fork&&(sessionJson.status==="STATUS_COMPLETED"||sessionJson.status==="STATUS_STOPPED"||sessionJson.status==="STATUS_ERRORED")&&(this.clearState(),this.beforeUnloadHandler&&(window.removeEventListener("beforeunload",this.beforeUnloadHandler),this.beforeUnloadHandler=null)),this.options.onSession&&this.options.onSession(sessionJson.status||"STATUS_UNSPECIFIED",sessionJson.fork)}};if(this.options.onOutput&&(handlers.onOutput=this.options.onOutput),handlers.onError=error=>{this.showErrorStatus(error),this.beforeUnloadHandler&&(window.removeEventListener("beforeunload",this.beforeUnloadHandler),this.beforeUnloadHandler=null)},!this.options.sessionToken&&this.resolvePersistOptions()&&await this.tryRestoreSession(handlers)!=="none"){this.updateBeforeUnloadGuard();return}if(this.options.sessionToken)this.sessionToken=this.options.sessionToken,await this.client.subscribe(this.sessionToken,handlers);else{const urlToken=this.parseInheritToken(),inheritToken=urlToken||this.options.inheritToken;if(this.options.inheritFrom&&!urlToken){const source="hash"in this.options.inheritFrom?`hash key '${this.options.inheritFrom.hash}'`:`param '${this.options.inheritFrom.param}'`;console.error(`[AdaptWebClient] No inherit token found in URL ${source}`);return}let challengeToken=this.options.challengeToken;if(this.options.requiresChallenge&&!challengeToken&&!inheritToken&&(challengeToken=await this.showCapWidgetAndSolve(),!challengeToken)){console.error("[AdaptWebClient] Failed to solve challenge");return}let result;if(inheritToken)result=await this.client.runInherit(inheritToken,handlers);else{const runOptions={...handlers};this.options.transmitter!==void 0&&(runOptions.transmitter=this.options.transmitter),this.options.signals!==void 0&&(runOptions.signals=this.options.signals),this.options.authToken!==void 0&&(runOptions.authToken=this.options.authToken),challengeToken!==void 0&&(runOptions.challengeToken=challengeToken),result=await this.client.run(runOptions)}this.sessionToken=result.sessionToken,this.sessionExpiresAt=result.expiresAt,this.saveState()}this.updateBeforeUnloadGuard()}async showCapWidgetAndSolve(){const CapWidgetClass=_AdaptWebClient._capWidgetClass;if(!CapWidgetClass)throw new Error("Cap.js not loaded. Import '@mochabug/adapt-web/cap' or use the full UMD bundle.");return new Promise(resolve=>{this.capWidgetInstance=new CapWidgetClass({container:this.rootElement,automationId:this.options.automationId,client:this.client.raw,...this.options.capWidgetOptions?.workerCount!==void 0&&{workerCount:this.options.capWidgetOptions.workerCount},...this.options.capWidgetOptions?.i18n&&{i18n:this.options.capWidgetOptions.i18n},onSolve:token=>{this.capWidgetInstance=null,resolve(token)},onError:error=>{console.error("[AdaptWebClient] Cap.js error:",error),this.capWidgetInstance=null,resolve(void 0)}}),this.darkMode&&this.capWidgetInstance.setDarkMode(!0)})}resolvePersistOptions(){const p=this.options.persist;if(!p)return null;if(p===!0)return{storage:"session",ttl:3600};const result={storage:p.storage??"session",ttl:p.ttl??3600};return p.key!==void 0&&(result.key=p.key),result}getStorageKey(){return`mb_adapt_${this.resolvePersistOptions()?.key??this.options.automationId}`}getStorage(){const opts=this.resolvePersistOptions();return opts?opts.storage==="local"?localStorage:sessionStorage:null}saveState(){const storage=this.getStorage();if(!storage||!this.sessionToken)return;const opts=this.resolvePersistOptions(),state={v:3,token:this.sessionToken,expiresAt:this.sessionExpiresAt?this.sessionExpiresAt.toISOString():null,savedAt:Date.now(),ttl:opts.ttl,mainUrl:this.mainUrl,mainToken:this.mainToken,forks:Array.from(this.forks.values()).filter(f=>!f.completed||f.recyclable).map(f=>{const pf={url:f.url,token:f.token,fork:f.fork,retentionPolicy:f.retentionPolicy};return f.source!==void 0&&(pf.source=f.source),pf}),forkDisplayMode:this.forkDisplay.mode,layout:this.panelManager?.serializeLayout()};if(this.minimizeManager){const minimizedIds=this.minimizeManager.getMinimizedGroupIds();minimizedIds.length>0&&(state.minimizedGroups=minimizedIds.map(gid=>{const entry=this.minimizeManager.getEntry(gid),persisted={groupId:gid,mode:entry?.mode??"floating"};return entry?.savedPosition&&(persisted.savedPosition={...entry.savedPosition}),persisted}))}const maxDockedId=this.getMaximizedDockedGroupId();maxDockedId&&(state.maximizedDockedGroupId=maxDockedId),storage.setItem(this.getStorageKey(),JSON.stringify(state))}loadState(){const storage=this.getStorage();if(!storage)return null;const raw=storage.getItem(this.getStorageKey());if(!raw)return null;let state;try{state=JSON.parse(raw)}catch{return this.clearState(),null}if(state.v!==3)return this.clearState(),null;const now=Date.now(),leeway=3e4;if(now-state.savedAt>state.ttl*1e3+leeway)return this.clearState(),null;if(state.expiresAt){const expires=new Date(state.expiresAt).getTime();if(now>expires+leeway)return this.clearState(),null}return state}clearState(){const storage=this.getStorage();storage&&storage.removeItem(this.getStorageKey())}async tryRestoreSession(handlers){const state=this.loadState();if(!state)return"none";const isStale=Date.now()-state.savedAt>1e4;if(this.sessionToken=state.token,this.sessionExpiresAt=state.expiresAt?new Date(state.expiresAt):void 0,this.mainUrl=state.mainUrl,this.mainToken=state.mainToken,state.forkDisplayMode&&(state.forkDisplayMode==="side-by-side"?this.forkDisplay={mode:"side-by-side"}:this.forkDisplay={mode:"dialog"}),this.mainUrl){const mainComponent=this.components.get(MAIN_PANEL_ID);mainComponent&&mainComponent.update({url:this.mainUrl,token:this.mainToken})}for(const pf of state.forks)this.restoreFork(pf);if(state.layout&&this.panelManager){for(const fg of state.layout.floatingGroups){const overlay=this.panelManager.getFloatingOverlay(fg.groupId);overlay&&(overlay.setFullBounds(fg.bounds),fg.isMaximized&&(overlay.maximize(),this.floatingToolbars.get(fg.groupId)?.syncMaximizedState()))}state.layout.mainLayout&&this.panelManager.restoreLayoutFlex(state.layout.mainLayout)}if(state.minimizedGroups&&this.minimizeManager&&this.panelManager)for(const mg of state.minimizedGroups){const group=this.panelManager.getGroup(mg.groupId);if(group&&!this.minimizeManager.isMinimized(mg.groupId))if(mg.mode==="floating"){const overlay=this.panelManager.getFloatingOverlay(mg.groupId);overlay&&this.minimizeManager.minimize(mg.groupId,overlay,group)}else mg.mode==="docked"&&this.minimizeManager.minimizeDocked(mg.groupId,group,this.panelManager)}if(state.maximizedDockedGroupId&&this.panelManager){const actions=this.forkGroupActions.get(state.maximizedDockedGroupId);actions&&actions.setMaximized()}isStale||handlers.onSession?.({status:"STATUS_RUNNING"}),this.saveState();let subscribeFailed=!1,errorWasSilenced=!1;const originalOnError=handlers.onError,wrappedHandlers={...handlers,onError:error=>{subscribeFailed=!0;const currentState=this.loadState();!currentState||Date.now()-currentState.savedAt>1e4?(errorWasSilenced=!0,this.clearState()):originalOnError?.(error)}};try{await this.client.subscribe(state.token,wrappedHandlers)}catch{subscribeFailed=!0,isStale?(errorWasSilenced=!0,this.clearState()):this.showErrorStatus(new Error("Session restore failed"))}return subscribeFailed?(await this.client.unsubscribe(),this.sessionToken=null,this.sessionExpiresAt=void 0,this.mainUrl=null,this.mainToken=void 0,this.clearAllForks(),this.components.get(MAIN_PANEL_ID)?.hide(),errorWasSilenced?"none":"failed"):"restored"}async newSession(){this.clearState(),this.mainCloseTimer&&(clearTimeout(this.mainCloseTimer),this.mainCloseTimer=null),this.mainRetentionPolicy="retain",this.sessionToken&&this.client.stop(this.sessionToken).catch(()=>{}),await this.client.unsubscribe(),this.mainUrl=null,this.mainToken=void 0,this.sessionToken=null,this.sessionExpiresAt=void 0,this.lastForkActive=null,this.updateBeforeUnloadGuard(),this.clearAllForks(),this.components.get(MAIN_PANEL_ID)?.hide(),this.removeStatusMessage();try{await this.init()}catch(error){this.showErrorStatus(error)}}resizeOverlayForGroup(group){if(!this.panelManager)return;const overlay=this.panelManager.findOverlayContaining(group.id);if(!overlay)return;const allGroups=overlay.getAllGroups();let maxHeight=0;for(const g of allGroups){const active=g.activePanel;if(active){const h=this.forkPanelHeights.get(active.id)??0;h>maxHeight&&(maxHeight=h)}}if(maxHeight>0){const headerHeight=group.headerElement?.offsetHeight??40,newHeight=Math.ceil(maxHeight)+headerHeight,bounds=overlay.getBounds(),newY=(window.innerHeight-newHeight)/2;overlay.setFullBounds({...bounds,height:newHeight,y:Math.max(0,newY)})}}onContainerResize(width,_height){if(!this.panelManager)return;const forkGroup=this.panelManager.getGroup(FORK_GROUP_ID);if(!forkGroup)return;const bp=this.responsiveBreakpoint,restoreThreshold=bp+this.responsiveHysteresis,forkActions=this.forkGroupActions.get(FORK_GROUP_ID),isDockedMaximized=forkActions?.isMaximized??!1;if(width<bp&&!this._autoMaximizedByResize){if(forkGroup.location==="floating"){const overlay=this.panelManager.getFloatingOverlay(FORK_GROUP_ID);overlay&&!overlay.isMaximized&&(overlay.maximize(),this._autoMaximizedByResize=!0)}else isDockedMaximized||(forkActions?(forkActions.setMaximized(),forkActions.setAutoMaximizedByResize(!0)):this.panelManager.maximizeDockedGroup(forkGroup),this._autoMaximizedByResize=!0);this.applyBestAutoResizeHeight()}width>=restoreThreshold&&this._autoMaximizedByResize&&(forkGroup.location==="floating"?this.panelManager.getFloatingOverlay(FORK_GROUP_ID)?.restore():forkActions?forkActions.clearMaximized():this.panelManager.restoreMaximizedDockedGroup(forkGroup),this._autoMaximizedByResize=!1,forkActions?.setAutoMaximizedByResize(!1))}setConfirmOnClose(enabled){this.confirmOnClose=enabled,this.updateBeforeUnloadGuard()}updateBeforeUnloadGuard(){const shouldGuard=this.confirmOnClose&&!!this.sessionToken&&!this.destroyed;shouldGuard&&!this.beforeUnloadHandler?(this.beforeUnloadHandler=e=>{e.preventDefault()},window.addEventListener("beforeunload",this.beforeUnloadHandler)):!shouldGuard&&this.beforeUnloadHandler&&(window.removeEventListener("beforeunload",this.beforeUnloadHandler),this.beforeUnloadHandler=null)}wireBeforeTabClose(){this.panelManager&&this.panelManager.setBeforeTabClose(panelId=>{if(this.removingPanelProgrammatically||!this.confirmOnClose)return!0;for(const[,state]of this.forks)if(state.panelId===panelId)return state.completed?!0:this.showConfirmDialog("This panel hasn\u2019t finished yet. Are you sure you want to close it?");return!0})}confirmCloseGroup(group){return!this.confirmOnClose||!group.panels.some(panel=>{for(const state of this.forks.values())if(state.panelId===panel.id&&!state.completed)return!0;return!1})?!0:this.showConfirmDialog("Some panels haven\u2019t finished yet. Are you sure you want to close them?")}showConfirmDialog(message){return new Promise(resolve=>{if(!this.rootElement){resolve(!0);return}const overlay=document.createElement("div");overlay.className="mb-adapt mb-adapt__confirm-overlay",this.darkMode&&overlay.classList.add("mb-adapt--dark");const card=document.createElement("div");card.className="mb-adapt__confirm-card";const text=document.createElement("p");text.className="mb-adapt__confirm-text",text.textContent=message,card.appendChild(text);const buttons=document.createElement("div");buttons.className="mb-adapt__confirm-buttons";const cancelBtn=document.createElement("button");cancelBtn.className="mb-adapt__confirm-btn mb-adapt__confirm-btn--cancel",cancelBtn.textContent="Cancel";const confirmBtn=document.createElement("button");confirmBtn.className="mb-adapt__confirm-btn mb-adapt__confirm-btn--confirm",confirmBtn.textContent="Close",buttons.appendChild(cancelBtn),buttons.appendChild(confirmBtn),card.appendChild(buttons),overlay.appendChild(card),document.body.appendChild(overlay);const cleanup=result=>{overlay.remove(),resolve(result)};cancelBtn.addEventListener("click",()=>cleanup(!1)),confirmBtn.addEventListener("click",()=>cleanup(!0)),overlay.addEventListener("click",e=>{e.target===overlay&&cleanup(!1)})})}async destroy(){this.destroyed=!0,this.mainCloseTimer&&(clearTimeout(this.mainCloseTimer),this.mainCloseTimer=null);for(const state of this.forks.values())state.closeTimer&&(clearTimeout(state.closeTimer),state.closeTimer=null);this.beforeUnloadHandler&&(window.removeEventListener("beforeunload",this.beforeUnloadHandler),this.beforeUnloadHandler=null),this.resizeObserver?.disconnect(),this.resizeObserver=null,this.capWidgetInstance?.destroy(),this.capWidgetInstance=null,this.minimizeManager?.dispose(),this.minimizeManager=null,this.sessionToken&&!this.loadState()&&this.client.stop(this.sessionToken).catch(()=>{}),await this.client.unsubscribe(),this.messageHandler&&window.removeEventListener("message",this.messageHandler),this.panelManager&&(this.panelManager.dispose(),this.panelManager=null),this.rootElement?.parentNode?.removeChild(this.rootElement),this.mainUrl=null,this.mainToken=void 0,this.forks.clear(),this.components.clear(),this.forkPanelHeights.clear(),this.forkGroupActions.clear(),this.floatingToolbars.clear(),this.sessionToken=null,this.lastForkActive=null,this.rootElement=null,this.messageHandler=null,this.statusMessageElement=null,this.minimizedTabsContainer=null}showStatusMessage(text,kind="error"){if(!this.rootElement)return;this.removeStatusMessage();const mainComponent=this.components.get(MAIN_PANEL_ID);mainComponent&&mainComponent.hide(),this.statusMessageElement=document.createElement("div"),this.statusMessageElement.className=this.options.classNames?.statusMessage??"mb-adapt__status-message";const card=document.createElement("div");card.className=this.options.classNames?.statusCard??"mb-adapt__status-card";const iconWrap=document.createElement("div");iconWrap.className=kind==="stopped"||kind==="expired"?"mb-adapt__status-icon mb-adapt__status-icon--stopped":"mb-adapt__status-icon",iconWrap.innerHTML=kind==="stopped"||kind==="expired"?'<svg viewBox="0 0 24 24" fill="none" stroke="#6b7280" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="6" y="6" width="12" height="12" rx="2"/></svg>':'<svg viewBox="0 0 24 24" fill="none" stroke="#ef4444" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>',card.appendChild(iconWrap);const msg=document.createElement("p");msg.className="mb-adapt__status-text",msg.textContent=text,card.appendChild(msg);const btn=document.createElement("button");btn.className="mb-adapt__status-restart",btn.textContent=this.options.text?.restartButton??"Try again",btn.addEventListener("click",()=>this.newSession()),card.appendChild(btn),this.statusMessageElement.appendChild(card),this.rootElement.appendChild(this.statusMessageElement)}removeStatusMessage(){this.statusMessageElement&&(this.statusMessageElement.remove(),this.statusMessageElement=null)}showErrorStatus(error){const kind=this.isExpiredTokenError(error)?"expired":"error";this.clearState(),this.clearAllForks(),this.showStatusMessage(this.getErrorMessage(error),kind)}isExpiredTokenError(error){return error instanceof ConnectError&&error.code===Code.PermissionDenied&&error.message.toLowerCase().includes("expired")}getErrorMessage(error){const text=this.options.text,fallback=text?.error??"Something went wrong. Please try again later.";if(error instanceof ConnectError){if(this.isExpiredTokenError(error))return text?.sessionExpired??"Your session has expired.";switch(error.code){case Code.ResourceExhausted:return text?.resourceExhausted??"This automation is currently at capacity. Please try again later.";case Code.NotFound:return error.message.toLowerCase().includes("session not found")?text?.sessionNotFound??"This session has timed out or been stopped.":text?.notFound??"This automation could not be found.";case Code.PermissionDenied:case Code.Unauthenticated:return text?.permissionDenied??"You don't have permission to run this automation.";default:return fallback}}return fallback}};_AdaptWebClient._capWidgetClass=null;let AdaptWebClient=_AdaptWebClient;export{AdaptAutomationElement,AdaptWebClient,FloatingToolbar2 as FloatingToolbar,ForkGroupActions2 as ForkGroupActions,IframePanelComponent2 as IframePanelComponent,MinimizeManager2 as MinimizeManager,PanelManager2 as PanelManager,clearPersistedState,configure,createConnectClient,resetConfig,resolveTheme2 as resolveTheme};
|
|
1
|
+
import{Code,configure,ConnectError,createAdaptClient,resetConfig}from"@mochabug/adapt-core";import{createConnectClient}from"@mochabug/adapt-core/connect";import{PanelManager}from"./panel-manager.js";import{FloatingToolbar,ForkGroupActions,IframePanelComponent,injectPanelManagerStyles,MinimizeManager}from"./panel-setup.js";import{resolveTheme}from"./theme.js";import{resolveTheme as resolveTheme2}from"./theme.js";import{AdaptAutomationElement}from"./AdaptAutomationElement.js";import{FloatingToolbar as FloatingToolbar2,ForkGroupActions as ForkGroupActions2,IframePanelComponent as IframePanelComponent2,MinimizeManager as MinimizeManager2}from"./panel-setup.js";import{PanelManager as PanelManager2}from"./panel-manager.js";function clearPersistedState(automationId,storage="both",persistKey){const key=`mb_adapt_${persistKey??automationId}`;(storage==="session"||storage==="both")&&sessionStorage.removeItem(key),(storage==="local"||storage==="both")&&localStorage.removeItem(key)}const MAIN_PANEL_ID="main",FORK_GROUP_ID="fork-group",DEFAULT_RESPONSIVE_BREAKPOINT=768,DEFAULT_RESPONSIVE_HYSTERESIS=40,_AdaptWebClient=class _AdaptWebClient{constructor(options){this.rootElement=null;this.panelManager=null;this.mainUrl=null;this.sessionToken=null;this.forks=new Map;this.mainRetentionPolicy="retain";this.mainCloseTimer=null;this.components=new Map;this.floatingAutoResized=new Set;this.beforeUnloadHandler=null;this.resizeObserver=null;this._autoMaximizedByResize=!1;this.destroyed=!1;this.sessionTerminated=!1;this.removingPanelProgrammatically=!1;this.lastForkActive=null;this.messageHandler=null;this.minimizedTabsContainer=null;this.lastReportedContentHeight=0;this.forkPanelHeights=new Map;this.statusMessageElement=null;this.capWidgetInstance=null;this.minimizeManager=null;this.forkGroupActions=new Map;this.floatingToolbars=new Map;this.options=options;const fd=options.forkDisplay??{mode:"side-by-side"};this.forkDisplay=fd,this.darkMode=options.darkMode??!1,this.autoResizing=options.autoResizing??!1,this.allowFloating=options.allowFloating??!0,this.allowDocking=options.allowDocking??!0,this.allowDialogDocking=options.allowDialogDocking??!0,this.allowMinimize=options.allowMinimize??!0,this.allowMaximize=options.allowMaximize??!0,this.floatingAutoResize=options.floatingAutoResize??!1,this.confirmOnClose=options.confirmOnClose??!1,this.theme=options.theme;const container=typeof options.container=="string"?document.getElementById(options.container):options.container;if(!container)throw new Error(`Container with id '${options.container}' not found`);this.container=container;const rawClient=createConnectClient({id:options.automationId});this.client=createAdaptClient(rawClient,options.automationId),injectPanelManagerStyles(),this.createRootElement(),this.createPanelManager(),this.wireBeforeTabClose(),this.setupMessageListener(),this.init().catch(error=>{this.showErrorStatus(error)})}static registerCapWidget(cls){_AdaptWebClient._capWidgetClass=cls}get responsiveBreakpoint(){if(!this.rootElement)return DEFAULT_RESPONSIVE_BREAKPOINT;const v=getComputedStyle(this.rootElement).getPropertyValue("--mb-adapt-responsive-breakpoint").trim(),n=Number(v);return n>0?n:DEFAULT_RESPONSIVE_BREAKPOINT}get responsiveHysteresis(){if(!this.rootElement)return DEFAULT_RESPONSIVE_HYSTERESIS;const v=getComputedStyle(this.rootElement).getPropertyValue("--mb-adapt-responsive-hysteresis").trim(),n=Number(v);return n>=0?n:DEFAULT_RESPONSIVE_HYSTERESIS}onComponentCreated(panelId,component){this.components.set(panelId,component)}onComponentDisposed(panelId){this.components.delete(panelId)}getDarkMode(){return this.darkMode}getClassNames(){return this.options.classNames}createPanelManager(){if(!this.rootElement)return;this.minimizeManager=new MinimizeManager,this.minimizeManager.setAllowDocking(this.allowDocking),this.minimizedTabsContainer=document.createElement("div"),this.minimizedTabsContainer.className="mb-adapt-minimized-tabs",this.rootElement.appendChild(this.minimizedTabsContainer),this.panelManager=new PanelManager({container:this.rootElement,onGroupCreatedByDrag:group=>{group.dragConstraint="merge-only",this.allowDocking||(group.dockingBlocked=!0),this.allowDialogDocking||(group.dialogDockingBlocked=!0),this.setupForkGroupActions(group)}});const mainGroup=this.panelManager.addGroup({id:"main-group"});this.panelManager.setMainGroup(mainGroup),mainGroup.locked="no-drop-target",mainGroup.setHeaderHidden(!0),mainGroup.element.setAttribute("data-main-group","true");const mainComponent=new IframePanelComponent(this);mainComponent.init(MAIN_PANEL_ID,{}),this.panelManager.addPanel({id:MAIN_PANEL_ID,element:mainComponent.element,groupId:mainGroup.id}),this.minimizeManager.init(this.minimizedTabsContainer,this.panelManager),this.minimizeManager.onBarVisibilityChanged(()=>{this.reapplyAutoResizeHeight()}),this.resizeObserver=new ResizeObserver(entries=>{const cr=entries[0]?.contentRect;cr&&this.onContainerResize(cr.width,cr.height)}),this.resizeObserver.observe(this.rootElement)}getOrigin(url){try{return new URL(url).origin}catch{return null}}isValidMessageOrigin(origin){if(this.mainUrl){const mainOrigin=this.getOrigin(this.mainUrl);if(mainOrigin&&origin===mainOrigin)return!0}for(const fork of this.forks.values()){const forkOrigin=this.getOrigin(fork.url);if(forkOrigin&&origin===forkOrigin)return!0}return!1}findComponentBySource(source){for(const[panelId,component]of this.components)if(component.contentWindow===source)return{panelId,component};return null}setupMessageListener(){this.messageHandler=event=>{if(!this.isValidMessageOrigin(event.origin))return;const data=event.data;if(!data||typeof data!="object")return;const source=event.source,found=this.findComponentBySource(source);if(!found)return;const{panelId,component}=found,isMainPanel=panelId===MAIN_PANEL_ID;if(data.type==="adapt-init"&&typeof data.resize=="boolean"){component.resizeCapable=data.resize,isMainPanel&&!data.resize&&this.rootElement&&(this.rootElement.style.height="");const targetOrigin=component.getOrigin();if(targetOrigin){let effective;if(isMainPanel)effective=this.autoResizing&&data.resize;else{const group=this.panelManager?.getPanel(panelId)?.group,inFloating=group?!!this.panelManager?.findOverlayContaining(group.id):!1;effective=data.resize&&(inFloating&&this.floatingAutoResize||!inFloating&&this.autoResizing)}component.postMessage({type:"adapt-autoResizing",autoResizing:effective},targetOrigin),component.postMessage({type:"adapt-darkMode",darkMode:this.darkMode},targetOrigin)}return}if(data.type==="adapt-resize"){const{height}=data;if(typeof height!="number"||!Number.isFinite(height)||height<1)return;if(isMainPanel)this.lastReportedContentHeight=height,component.resizeCapable&&this.autoResizing&&this.rootElement&&this.applyBestAutoResizeHeight();else{this.forkPanelHeights.set(panelId,height);const group=this.panelManager?.getPanel(panelId)?.group;if(group&&group.activePanel?.id===panelId){const inFloating=!!this.panelManager?.findOverlayContaining(group.id);!inFloating&&component.resizeCapable&&this.autoResizing&&this.rootElement&&this.applyBestAutoResizeHeight(),inFloating&&this.floatingAutoResize&&(this.floatingAutoResized.has(group.id)||(this.floatingAutoResized.add(group.id),this.resizeOverlayForGroup(group)))}}return}},window.addEventListener("message",this.messageHandler)}postToComponent(component,message){const origin=component.getOrigin();origin&&component.postMessage(message,origin)}setDarkMode(darkMode){if(this.darkMode===darkMode)return;this.darkMode=darkMode,this.rootElement?.classList.toggle("mb-adapt--dark",darkMode),this.capWidgetInstance?.setDarkMode(darkMode),this.applyTheme();const msg={type:"adapt-darkMode",darkMode};for(const c of this.components.values())this.postToComponent(c,msg)}setTheme(theme){if(this.theme=theme,this.clearThemeVars(),theme?.mode!==void 0){const dark=theme.mode==="dark";if(this.darkMode!==dark){this.setDarkMode(dark);return}}this.applyTheme()}clearThemeVars(){if(!(!this.rootElement||!this._appliedThemeVars)){for(const key of this._appliedThemeVars)this.rootElement.style.removeProperty(key);this._appliedThemeVars=void 0}}applyTheme(){if(!this.rootElement||!this.theme)return;const vars=resolveTheme(this.theme);for(const[key,value]of Object.entries(vars))this.rootElement.style.setProperty(key,value);this._appliedThemeVars=Object.keys(vars)}setAutoResizing(autoResizing){if(this.autoResizing===autoResizing)return;this.autoResizing=autoResizing;const mainComponent=this.components.get(MAIN_PANEL_ID);mainComponent?.resizeCapable&&this.postToComponent(mainComponent,{type:"adapt-autoResizing",autoResizing});for(const[panelId,component]of this.components){if(panelId===MAIN_PANEL_ID||!component.resizeCapable)continue;const group=this.panelManager?.getPanel(panelId)?.group;group&&this.panelManager?.findOverlayContaining(group.id)||this.postToComponent(component,{type:"adapt-autoResizing",autoResizing})}!autoResizing&&this.rootElement&&(this.rootElement.style.height="")}setAllowFloating(allow){if(this.allowFloating!==allow){this.allowFloating=allow;for(const actions of this.forkGroupActions.values())actions.setAllowFloating(allow)}}setAllowDocking(allow){if(this.allowDocking!==allow){if(this.allowDocking=allow,this.minimizeManager?.setAllowDocking(allow),this.panelManager)for(const group of this.getAllForkGroups())group.dockingBlocked=!allow;for(const toolbar of this.floatingToolbars.values())toolbar.setAllowDocking(allow)}}setAllowDialogDocking(allow){if(this.allowDialogDocking!==allow&&(this.allowDialogDocking=allow,this.panelManager))for(const group of this.getAllForkGroups())group.dialogDockingBlocked=!allow}setAllowMinimize(allow){if(this.allowMinimize!==allow){this.allowMinimize=allow;for(const actions of this.forkGroupActions.values())actions.setAllowMinimize(allow);for(const toolbar of this.floatingToolbars.values())toolbar.setAllowMinimize(allow)}}setAllowMaximize(allow){if(this.allowMaximize!==allow){this.allowMaximize=allow;for(const actions of this.forkGroupActions.values())actions.setAllowMaximize(allow);for(const toolbar of this.floatingToolbars.values())toolbar.setAllowMaximize(allow)}}setFloatingAutoResize(enabled){if(this.floatingAutoResize!==enabled){this.floatingAutoResize=enabled,this.floatingAutoResized.clear();for(const[panelId,component]of this.components){if(panelId===MAIN_PANEL_ID||!component.resizeCapable)continue;const group=this.panelManager?.getPanel(panelId)?.group,effective=(group?!!this.panelManager?.findOverlayContaining(group.id):!1)?enabled&&component.resizeCapable:this.autoResizing&&component.resizeCapable;this.postToComponent(component,{type:"adapt-autoResizing",autoResizing:effective})}}}getAllForkGroups(){if(!this.panelManager)return[];const seen=new Set,groups=[],add=g=>{g.id==="main-group"||seen.has(g.id)||(seen.add(g.id),groups.push(g))},forkGroup=this.panelManager.getGroup(FORK_GROUP_ID);forkGroup&&add(forkGroup);for(const g of this.panelManager.getDockedGroups())add(g);for(const[,overlay]of this.panelManager.getFloatingOverlays())for(const g of overlay.getAllGroups())add(g);return groups}applyAutoResizeHeight(contentHeight){if(!this.rootElement)return;const chrome=this.minimizedTabsContainer?.offsetHeight??0;this.rootElement.style.height=`${Math.ceil(contentHeight)+chrome}px`}applyBestAutoResizeHeight(){if(!this.autoResizing||!this.rootElement)return;let maxHeight=0;if(this.components.get(MAIN_PANEL_ID)?.resizeCapable&&this.lastReportedContentHeight>0){const mainGroup=this.panelManager?.getMainGroup();if(mainGroup?mainGroup.element.offsetHeight>0:!0){const headerH=mainGroup?.headerElement?.offsetHeight??0;maxHeight=this.lastReportedContentHeight+headerH}}for(const group of this.getAllForkGroups()){if(this.panelManager?.findOverlayContaining(group.id)||group.element.offsetHeight<=0)continue;const active=group.activePanel;if(active){const h=this.forkPanelHeights.get(active.id)??0,headerH=group.headerElement?.offsetHeight??0,total=h+headerH;total>maxHeight&&(maxHeight=total)}}maxHeight>0&&this.applyAutoResizeHeight(maxHeight)}reapplyAutoResizeHeight(){this.applyBestAutoResizeHeight()}setForkDisplayMode(mode){this.forkDisplay.mode!==mode&&(mode==="side-by-side"?this.forkDisplay={mode:"side-by-side"}:this.forkDisplay={mode:"dialog"},this.forks.size>0&&this.panelManager&&this.rebuildForkGroup(),this.emitForkActive(),this.saveState())}createRootElement(){this.rootElement=document.createElement("div"),this.rootElement.className=this.options.classNames?.root||"mb-adapt",this.darkMode&&this.rootElement.classList.add("mb-adapt--dark"),this.options.styles&&Object.assign(this.rootElement.style,this.options.styles),this.applyTheme(),this.container.appendChild(this.rootElement)}onUrl(msg){if(this.destroyed)return;const fork=msg.fork||"";if(msg.stopped){this.handleStoppedMessage(fork),this.saveState();return}if(msg.done){this.handleDoneMessage(fork,msg.retentionPolicy),this.saveState();return}msg.url&&(fork?this.handleForkUrl(msg.url,msg.token,fork,msg.source,msg.retentionPolicy):this.handleMainUrl(msg.url,msg.token,msg.source,msg.retentionPolicy),this.saveState())}handleMainUrl(url,token,_source,retentionPolicy){this.mainCloseTimer&&(clearTimeout(this.mainCloseTimer),this.mainCloseTimer=null);const wasMainEmpty=!this.mainUrl;if(this.removeStatusMessage(),this.mainUrl=url,this.mainToken=token,this.mainRetentionPolicy=this.resolveRetention(retentionPolicy),this.panelManager?.isMainGroupCollapsed()&&this.panelManager.expandMainGroup(),wasMainEmpty){const maximizedGroupId=this.getMaximizedDockedGroupId();if(maximizedGroupId){const actions=this.forkGroupActions.get(maximizedGroupId);actions&&actions.clearMaximized()}}const mainComponent=this.components.get(MAIN_PANEL_ID);mainComponent&&(mainComponent.update({url,token}),mainComponent.show())}handleForkUrl(url,token,fork,source,retentionPolicy){if(!this.panelManager)return;const resolved=this.resolveRetention(retentionPolicy),existing=this.forks.get(fork);if(existing){existing.closeTimer&&(clearTimeout(existing.closeTimer),existing.closeTimer=null),existing.url=url,existing.token=token,existing.source=source,existing.retentionPolicy=resolved,existing.completed=!1,existing.recyclable=!1;const component2=this.components.get(existing.panelId);component2&&component2.update({url,token});return}const recyclable=this.findRecyclablePanel(source);if(recyclable){const{forkKey:oldFork,state:rState}=recyclable;rState.closeTimer&&(clearTimeout(rState.closeTimer),rState.closeTimer=null),this.forks.delete(oldFork),rState.url=url,rState.token=token,rState.fork=fork,rState.source=source,rState.retentionPolicy=resolved,rState.completed=!1,rState.recyclable=!1,this.forks.set(fork,rState);const component2=this.components.get(rState.panelId);component2&&component2.update({url,token});return}const panelId=`fork-${fork}`;this.ensureForkGroup(),!this.mainUrl&&this.panelManager&&!this.panelManager.isMainGroupCollapsed()&&this.panelManager.collapseMainGroup();const component=new IframePanelComponent(this);component.init(panelId,{url,token}),this.panelManager.addPanel({id:panelId,element:component.element,groupId:FORK_GROUP_ID}),this.forks.set(fork,{panelId,url,token,fork,source,completed:!1,recyclable:!1,retentionPolicy:resolved,closeTimer:null}),this.emitForkActive()}ensureForkGroup(){if(!this.panelManager||this.panelManager.getGroup(FORK_GROUP_ID))return;const cw=this.rootElement?.offsetWidth??800,ch=this.rootElement?.offsetHeight??600;if(this.forkDisplay.mode==="dialog"){const isSmall=cw<this.responsiveBreakpoint,vw=window.innerWidth,vh=window.innerHeight,fw=isSmall?Math.min(cw*.95,Math.max(200,vw-20)):Math.min(720,cw*.9),fh=isSmall?Math.min(ch*.9,Math.max(200,vh-20)):Math.min(ch*.8,600),group=this.panelManager.addGroup({id:FORK_GROUP_ID,floating:{width:fw,height:fh,x:Math.max(0,(vw-fw)/2),y:Math.max(0,(vh-fh)/2)}});group.dragConstraint="merge-only",this.allowDocking||(group.dockingBlocked=!0),this.allowDialogDocking||(group.dialogDockingBlocked=!0),this.setupForkGroupActions(group),isSmall&&(this.panelManager.getFloatingOverlay(FORK_GROUP_ID)?.maximize(),this._autoMaximizedByResize=!0)}else{const split=this.forkDisplay.mode==="side-by-side"?this.forkDisplay.split:void 0,initialWidth=split!==void 0?cw*(1-split/100):void 0,group=this.panelManager.addGroup({id:FORK_GROUP_ID,direction:"right",initialSize:initialWidth});if(group.dragConstraint="merge-only",this.allowDocking||(group.dockingBlocked=!0),this.allowDialogDocking||(group.dialogDockingBlocked=!0),this.setupForkGroupActions(group),cw<this.responsiveBreakpoint){const fa=this.forkGroupActions.get(group.id);fa?(fa.setMaximized(),fa.setAutoMaximizedByResize(!0)):this.panelManager.maximizeDockedGroup(group),this._autoMaximizedByResize=!0}}}setupForkGroupActions(group){if(!this.panelManager||!this.minimizeManager)return;const actions=new ForkGroupActions(group,this.minimizeManager,this.panelManager,()=>{if(this.setupFloatingToolbar(group),group.location==="grid"&&!this.mainUrl&&this.panelManager&&!this.panelManager.isMainGroupCollapsed()&&this.panelManager.collapseMainGroup(),group.location==="floating"&&this.floatingAutoResized.delete(group.id),this.updateAutoResizeForGroup(group),group.location==="grid"){const currentWidth=this.rootElement?.offsetWidth??0;if(currentWidth>0&¤tWidth<this.responsiveBreakpoint){const fa=this.forkGroupActions.get(group.id);fa&&!fa.isMaximized&&(fa.setMaximized(),this._autoMaximizedByResize=!0,fa.setAutoMaximizedByResize(!0))}}},{allowFloating:this.allowFloating,allowMinimize:this.allowMinimize,allowMaximize:this.allowMaximize});actions.setBeforeClose(()=>this.confirmCloseGroup(group)),actions.onMaximizeChanged(maximized=>{maximized||(this._autoMaximizedByResize=!1,actions.setAutoMaximizedByResize(!1))}),group.setHeaderActions(actions.element),this.forkGroupActions.set(group.id,actions),group.onActivePanelChanged(()=>{this.autoResizing&&this.rootElement&&this.applyBestAutoResizeHeight()}),this.setupFloatingToolbar(group)}updateAutoResizeForGroup(group){const inFloating=this.panelManager?!!this.panelManager.findOverlayContaining(group.id):!1;for(const panel of group.panels){const component=this.components.get(panel.id);if(!component?.resizeCapable)continue;const effective=inFloating?this.floatingAutoResize:this.autoResizing;this.postToComponent(component,{type:"adapt-autoResizing",autoResizing:effective})}}setupFloatingToolbar(group){if(!this.panelManager||!this.minimizeManager)return;const overlay=this.panelManager.findOverlayContaining(group.id);if(overlay)if(group.onPanelCountChanged(()=>overlay.updateTotalTabCount()),overlay.hasToolbar)overlay.repositionToolbar();else{const toolbar=new FloatingToolbar(overlay,this.panelManager,this.minimizeManager,{allowDocking:this.allowDocking,allowMinimize:this.allowMinimize,allowMaximize:this.allowMaximize});toolbar.setBeforeClose(()=>this.confirmCloseGroup(overlay.group)),overlay.setToolbar(toolbar.element),this.floatingToolbars.set(overlay.group.id,toolbar),overlay.updateTotalTabCount()}}resolveRetention(policy){return policy?policy.case:"retain"}findRecyclablePanel(source){let anyRecyclable=null;for(const[forkKey,state]of this.forks)if(state.recyclable){if(source&&state.source===source)return{forkKey,state};anyRecyclable||(anyRecyclable={forkKey,state})}return anyRecyclable}handleMainDone(retentionPolicy){switch(retentionPolicy?this.resolveRetention(retentionPolicy):this.mainRetentionPolicy){case"close":this.scheduleMainClose(retentionPolicy?.case==="close"?retentionPolicy.timeoutSeconds:void 0);break;case"recycle":break;default:break}}scheduleForkClose(fork,state,timeoutSeconds){const doClose=()=>{state.closeTimer=null,this.removingPanelProgrammatically=!0;try{if(this.panelManager){const component=this.components.get(state.panelId);component&&component.dispose(),this.panelManager.removePanel(state.panelId)}this.forks.delete(fork),this.removeForkGroupIfEmpty()}finally{this.removingPanelProgrammatically=!1}this.emitForkActive(),this.saveState()};timeoutSeconds&&timeoutSeconds>0?state.closeTimer=setTimeout(doClose,timeoutSeconds*1e3):doClose()}scheduleMainClose(timeoutSeconds){const doClose=()=>{this.mainCloseTimer=null,this.mainUrl=null,this.mainToken=void 0;const mainComponent=this.components.get(MAIN_PANEL_ID);mainComponent&&mainComponent.hide(),this.panelManager&&!this.panelManager.isMainGroupCollapsed()&&this.panelManager.collapseMainGroup(),this.saveState()};timeoutSeconds&&timeoutSeconds>0?this.mainCloseTimer=setTimeout(doClose,timeoutSeconds*1e3):doClose()}restoreFork(pf){if(!this.panelManager)return;const panelId=`fork-${pf.fork}`;this.ensureForkGroup(),!this.mainUrl&&this.panelManager&&!this.panelManager.isMainGroupCollapsed()&&this.panelManager.collapseMainGroup();const component=new IframePanelComponent(this);component.init(panelId,{url:pf.url,token:pf.token}),this.panelManager.addPanel({id:panelId,element:component.element,groupId:FORK_GROUP_ID}),this.forks.set(pf.fork,{panelId,url:pf.url,token:pf.token,fork:pf.fork,source:pf.source,completed:!1,recyclable:pf.retentionPolicy==="recycle",retentionPolicy:pf.retentionPolicy,closeTimer:null}),this.emitForkActive()}clearAllForks(){this.removingPanelProgrammatically=!0;try{if(this.panelManager)for(const state of this.forks.values()){state.closeTimer&&(clearTimeout(state.closeTimer),state.closeTimer=null);const component=this.components.get(state.panelId);component&&component.dispose(),this.panelManager.removePanel(state.panelId)}this.forks.clear(),this.removeForkGroupIfEmpty()}finally{this.removingPanelProgrammatically=!1}}rebuildForkGroup(){if(!this.panelManager)return;const group=this.panelManager.getGroup(FORK_GROUP_ID);if(group)if(this.forkDisplay.mode==="dialog"){const cw=this.rootElement?.offsetWidth??800,ch=this.rootElement?.offsetHeight??600,fw=Math.min(720,cw*.9),fh=Math.min(ch*.8,600);this.panelManager.addFloatingGroup(group,{width:fw,height:fh,x:(window.innerWidth-fw)/2,y:(window.innerHeight-fh)/2}),this.setupFloatingToolbar(group)}else{const split=this.forkDisplay.mode==="side-by-side"?this.forkDisplay.split:void 0,initialWidth=split!==void 0?(this.rootElement?.offsetWidth??800)*(1-split/100):void 0;this.panelManager.dockGroup(FORK_GROUP_ID,"right",initialWidth)}}handleSessionComplete(){this.clearAllForks(),this.emitForkActive()}handleDoneMessage(fork,retentionPolicy){if(!fork){this.handleMainDone(retentionPolicy);return}const state=this.forks.get(fork);if(!state)return;switch(retentionPolicy?this.resolveRetention(retentionPolicy):state.retentionPolicy){case"close":state.completed=!0,this.scheduleForkClose(fork,state,retentionPolicy?.case==="close"?retentionPolicy.timeoutSeconds:void 0);break;case"recycle":state.completed=!0,state.recyclable=!0;break;default:state.completed=!0;break}}handleStoppedMessage(fork){if(!fork){this.mainCloseTimer&&(clearTimeout(this.mainCloseTimer),this.mainCloseTimer=null),this.mainUrl=null,this.mainToken=void 0;const mainComponent=this.components.get(MAIN_PANEL_ID);mainComponent&&mainComponent.hide(),this.showStatusMessage(this.options.text?.stopped??"This session has been stopped","stopped");return}const state=this.forks.get(fork);if(state){state.closeTimer&&(clearTimeout(state.closeTimer),state.closeTimer=null),this.removingPanelProgrammatically=!0;try{if(this.panelManager){const component=this.components.get(state.panelId);component&&component.dispose(),this.panelManager.removePanel(state.panelId)}this.forks.delete(fork),this.removeForkGroupIfEmpty()}finally{this.removingPanelProgrammatically=!1}this.emitForkActive()}}removeForkGroupIfEmpty(){if(!this.panelManager)return;const g=this.panelManager.getGroup(FORK_GROUP_ID);g&&g.size===0&&(this.panelManager.removeGroup(FORK_GROUP_ID),this._autoMaximizedByResize=!1,this.forkGroupActions.delete(FORK_GROUP_ID),this.floatingToolbars.delete(FORK_GROUP_ID),this.floatingAutoResized.delete(FORK_GROUP_ID)),this.minimizeManager?.removeGroup(FORK_GROUP_ID)}getMaximizedDockedGroupId(){for(const[groupId,actions]of this.forkGroupActions)if(actions.isMaximized)return groupId}emitForkActive(){if(!this.options.onForkActive)return;const active=this.forks.size>0;active!==this.lastForkActive&&(this.lastForkActive=active,this.options.onForkActive(active))}parseInheritToken(){const inheritFrom=this.options.inheritFrom;return inheritFrom?"hash"in inheritFrom?this.parseFromHash(inheritFrom.hash):this.parseFromParam(inheritFrom.param):null}parseFromHash(key){const hash=window.location.hash.slice(1);if(!hash)return null;const params=new URLSearchParams(hash),token=params.get(key);if(!token)return null;params.delete(key);const newHash=params.toString(),newUrl=window.location.pathname+window.location.search+(newHash?"#"+newHash:"");return history.replaceState(null,"",newUrl),decodeURIComponent(token)}parseFromParam(key){const params=new URLSearchParams(window.location.search),token=params.get(key);if(!token)return null;params.delete(key);const newSearch=params.toString(),newUrl=window.location.pathname+(newSearch?"?"+newSearch:"")+window.location.hash;return history.replaceState(null,"",newUrl),decodeURIComponent(token)}async init(){this.panelManager?.onDidRemovePanel(panel=>{if(!this.removingPanelProgrammatically){for(const[fork,state]of this.forks)if(state.panelId===panel.id){state.closeTimer&&(clearTimeout(state.closeTimer),state.closeTimer=null);const component=this.components.get(state.panelId);component&&component.dispose(),this.sessionToken&&this.client.stop(this.sessionToken,fork).catch(()=>{}),this.forks.delete(fork);break}this.emitForkActive()}});const handlers={onUrl:msg=>this.onUrl(msg),onSession:sessionJson=>{sessionJson.status==="STATUS_COMPLETED"&&!sessionJson.fork&&this.handleSessionComplete(),!sessionJson.fork&&(sessionJson.status==="STATUS_COMPLETED"||sessionJson.status==="STATUS_STOPPED"||sessionJson.status==="STATUS_ERRORED"||sessionJson.status==="STATUS_DELEGATED"||sessionJson.status==="STATUS_EXPIRED")&&(this.sessionTerminated=!0,this.clearState(),this.beforeUnloadHandler&&(window.removeEventListener("beforeunload",this.beforeUnloadHandler),this.beforeUnloadHandler=null)),this.options.onSession&&this.options.onSession(sessionJson.status||"STATUS_UNSPECIFIED",sessionJson.fork)}};if(this.options.onOutput&&(handlers.onOutput=this.options.onOutput),handlers.onError=error=>{this.showErrorStatus(error),this.beforeUnloadHandler&&(window.removeEventListener("beforeunload",this.beforeUnloadHandler),this.beforeUnloadHandler=null)},!this.options.sessionToken&&this.resolvePersistOptions()&&await this.tryRestoreSession(handlers)!=="none"){this.updateBeforeUnloadGuard();return}if(this.options.sessionToken)this.sessionToken=this.options.sessionToken,await this.client.subscribe(this.sessionToken,handlers);else{const urlToken=this.parseInheritToken(),inheritToken=urlToken||this.options.inheritToken;if(this.options.inheritFrom&&!urlToken){const source="hash"in this.options.inheritFrom?`hash key '${this.options.inheritFrom.hash}'`:`param '${this.options.inheritFrom.param}'`;console.error(`[AdaptWebClient] No inherit token found in URL ${source}`);return}let challengeToken=this.options.challengeToken;if(this.options.requiresChallenge&&!challengeToken&&!inheritToken&&(challengeToken=await this.showCapWidgetAndSolve(),!challengeToken)){console.error("[AdaptWebClient] Failed to solve challenge");return}let result;if(inheritToken)result=await this.client.runInherit(inheritToken,handlers);else{const runOptions={...handlers};this.options.transmitter!==void 0&&(runOptions.transmitter=this.options.transmitter),this.options.signals!==void 0&&(runOptions.signals=this.options.signals),this.options.authToken!==void 0&&(runOptions.authToken=this.options.authToken),challengeToken!==void 0&&(runOptions.challengeToken=challengeToken),result=await this.client.run(runOptions)}this.sessionToken=result.sessionToken,this.sessionExpiresAt=result.expiresAt,this.saveState()}this.updateBeforeUnloadGuard()}async showCapWidgetAndSolve(){const CapWidgetClass=_AdaptWebClient._capWidgetClass;if(!CapWidgetClass)throw new Error("Cap.js not loaded. Import '@mochabug/adapt-web/cap' or use the full UMD bundle.");return new Promise(resolve=>{this.capWidgetInstance=new CapWidgetClass({container:this.rootElement,automationId:this.options.automationId,client:this.client.raw,...this.options.capWidgetOptions?.workerCount!==void 0&&{workerCount:this.options.capWidgetOptions.workerCount},...this.options.capWidgetOptions?.i18n&&{i18n:this.options.capWidgetOptions.i18n},onSolve:token=>{this.capWidgetInstance=null,resolve(token)},onError:error=>{console.error("[AdaptWebClient] Cap.js error:",error),this.capWidgetInstance=null,resolve(void 0)}}),this.darkMode&&this.capWidgetInstance.setDarkMode(!0)})}resolvePersistOptions(){const p=this.options.persist;if(!p)return null;if(p===!0)return{storage:"session",ttl:3600};const result={storage:p.storage??"session",ttl:p.ttl??3600};return p.key!==void 0&&(result.key=p.key),result}getStorageKey(){return`mb_adapt_${this.resolvePersistOptions()?.key??this.options.automationId}`}getStorage(){const opts=this.resolvePersistOptions();return opts?opts.storage==="local"?localStorage:sessionStorage:null}saveState(){const storage=this.getStorage();if(!storage||!this.sessionToken)return;const opts=this.resolvePersistOptions(),state={v:3,token:this.sessionToken,expiresAt:this.sessionExpiresAt?this.sessionExpiresAt.toISOString():null,savedAt:Date.now(),ttl:opts.ttl,mainUrl:this.mainUrl,mainToken:this.mainToken,forks:Array.from(this.forks.values()).filter(f=>!f.completed||f.recyclable).map(f=>{const pf={url:f.url,token:f.token,fork:f.fork,retentionPolicy:f.retentionPolicy};return f.source!==void 0&&(pf.source=f.source),pf}),forkDisplayMode:this.forkDisplay.mode,layout:this.panelManager?.serializeLayout()};if(this.minimizeManager){const minimizedIds=this.minimizeManager.getMinimizedGroupIds();minimizedIds.length>0&&(state.minimizedGroups=minimizedIds.map(gid=>{const entry=this.minimizeManager.getEntry(gid),persisted={groupId:gid,mode:entry?.mode??"floating"};return entry?.savedPosition&&(persisted.savedPosition={...entry.savedPosition}),persisted}))}const maxDockedId=this.getMaximizedDockedGroupId();maxDockedId&&(state.maximizedDockedGroupId=maxDockedId),storage.setItem(this.getStorageKey(),JSON.stringify(state))}loadState(){const storage=this.getStorage();if(!storage)return null;const raw=storage.getItem(this.getStorageKey());if(!raw)return null;let state;try{state=JSON.parse(raw)}catch{return this.clearState(),null}if(state.v!==3)return this.clearState(),null;const now=Date.now(),leeway=3e4;if(now-state.savedAt>state.ttl*1e3+leeway)return this.clearState(),null;if(state.expiresAt){const expires=new Date(state.expiresAt).getTime();if(now>expires+leeway)return this.clearState(),null}return state}clearState(){const storage=this.getStorage();storage&&storage.removeItem(this.getStorageKey())}async tryRestoreSession(handlers){const state=this.loadState();if(!state)return"none";const isStale=Date.now()-state.savedAt>1e4;if(this.sessionToken=state.token,this.sessionExpiresAt=state.expiresAt?new Date(state.expiresAt):void 0,this.mainUrl=state.mainUrl,this.mainToken=state.mainToken,state.forkDisplayMode&&(state.forkDisplayMode==="side-by-side"?this.forkDisplay={mode:"side-by-side"}:this.forkDisplay={mode:"dialog"}),this.mainUrl){const mainComponent=this.components.get(MAIN_PANEL_ID);mainComponent&&mainComponent.update({url:this.mainUrl,token:this.mainToken})}for(const pf of state.forks)this.restoreFork(pf);if(state.layout&&this.panelManager){for(const fg of state.layout.floatingGroups){const overlay=this.panelManager.getFloatingOverlay(fg.groupId);overlay&&(overlay.setFullBounds(fg.bounds),fg.isMaximized&&(overlay.maximize(),this.floatingToolbars.get(fg.groupId)?.syncMaximizedState()))}state.layout.mainLayout&&this.panelManager.restoreLayoutFlex(state.layout.mainLayout)}if(state.minimizedGroups&&this.minimizeManager&&this.panelManager)for(const mg of state.minimizedGroups){const group=this.panelManager.getGroup(mg.groupId);if(group&&!this.minimizeManager.isMinimized(mg.groupId))if(mg.mode==="floating"){const overlay=this.panelManager.getFloatingOverlay(mg.groupId);overlay&&this.minimizeManager.minimize(mg.groupId,overlay,group)}else mg.mode==="docked"&&this.minimizeManager.minimizeDocked(mg.groupId,group,this.panelManager)}if(state.maximizedDockedGroupId&&this.panelManager){const actions=this.forkGroupActions.get(state.maximizedDockedGroupId);actions&&actions.setMaximized()}isStale||handlers.onSession?.({status:"STATUS_RUNNING"}),this.saveState();let subscribeFailed=!1,errorWasSilenced=!1;const originalOnError=handlers.onError,wrappedHandlers={...handlers,onError:error=>{subscribeFailed=!0;const currentState=this.loadState();!currentState||Date.now()-currentState.savedAt>1e4?(errorWasSilenced=!0,this.clearState()):originalOnError?.(error)}};try{await this.client.subscribe(state.token,wrappedHandlers)}catch{subscribeFailed=!0,isStale?(errorWasSilenced=!0,this.clearState()):this.showErrorStatus(new Error("Session restore failed"))}return subscribeFailed?(await this.client.unsubscribe(),this.sessionToken=null,this.sessionExpiresAt=void 0,this.mainUrl=null,this.mainToken=void 0,this.clearAllForks(),this.components.get(MAIN_PANEL_ID)?.hide(),errorWasSilenced?"none":"failed"):"restored"}async newSession(){this.clearState(),this.sessionTerminated=!1,this.mainCloseTimer&&(clearTimeout(this.mainCloseTimer),this.mainCloseTimer=null),this.mainRetentionPolicy="retain",this.sessionToken&&this.client.stop(this.sessionToken).catch(()=>{}),await this.client.unsubscribe(),this.mainUrl=null,this.mainToken=void 0,this.sessionToken=null,this.sessionExpiresAt=void 0,this.lastForkActive=null,this.updateBeforeUnloadGuard(),this.clearAllForks(),this.components.get(MAIN_PANEL_ID)?.hide(),this.removeStatusMessage();try{await this.init()}catch(error){this.showErrorStatus(error)}}resizeOverlayForGroup(group){if(!this.panelManager)return;const overlay=this.panelManager.findOverlayContaining(group.id);if(!overlay)return;const allGroups=overlay.getAllGroups();let maxHeight=0;for(const g of allGroups){const active=g.activePanel;if(active){const h=this.forkPanelHeights.get(active.id)??0;h>maxHeight&&(maxHeight=h)}}if(maxHeight>0){const headerHeight=group.headerElement?.offsetHeight??40,newHeight=Math.ceil(maxHeight)+headerHeight,bounds=overlay.getBounds(),newY=(window.innerHeight-newHeight)/2;overlay.setFullBounds({...bounds,height:newHeight,y:Math.max(0,newY)})}}onContainerResize(width,_height){if(!this.panelManager)return;const forkGroup=this.panelManager.getGroup(FORK_GROUP_ID);if(!forkGroup)return;const bp=this.responsiveBreakpoint,restoreThreshold=bp+this.responsiveHysteresis,forkActions=this.forkGroupActions.get(FORK_GROUP_ID),isDockedMaximized=forkActions?.isMaximized??!1;if(width<bp&&!this._autoMaximizedByResize){if(forkGroup.location==="floating"){const overlay=this.panelManager.getFloatingOverlay(FORK_GROUP_ID);overlay&&!overlay.isMaximized&&(overlay.maximize(),this._autoMaximizedByResize=!0)}else isDockedMaximized||(forkActions?(forkActions.setMaximized(),forkActions.setAutoMaximizedByResize(!0)):this.panelManager.maximizeDockedGroup(forkGroup),this._autoMaximizedByResize=!0);this.applyBestAutoResizeHeight()}width>=restoreThreshold&&this._autoMaximizedByResize&&(forkGroup.location==="floating"?this.panelManager.getFloatingOverlay(FORK_GROUP_ID)?.restore():forkActions?forkActions.clearMaximized():this.panelManager.restoreMaximizedDockedGroup(forkGroup),this._autoMaximizedByResize=!1,forkActions?.setAutoMaximizedByResize(!1))}setConfirmOnClose(enabled){this.confirmOnClose=enabled,this.updateBeforeUnloadGuard()}updateBeforeUnloadGuard(){const shouldGuard=this.confirmOnClose&&!!this.sessionToken&&!this.destroyed;shouldGuard&&!this.beforeUnloadHandler?(this.beforeUnloadHandler=e=>{e.preventDefault()},window.addEventListener("beforeunload",this.beforeUnloadHandler)):!shouldGuard&&this.beforeUnloadHandler&&(window.removeEventListener("beforeunload",this.beforeUnloadHandler),this.beforeUnloadHandler=null)}wireBeforeTabClose(){this.panelManager&&this.panelManager.setBeforeTabClose(panelId=>{if(this.removingPanelProgrammatically||!this.confirmOnClose)return!0;for(const[,state]of this.forks)if(state.panelId===panelId)return state.completed?!0:this.showConfirmDialog("This panel hasn\u2019t finished yet. Are you sure you want to close it?");return!0})}confirmCloseGroup(group){return!this.confirmOnClose||!group.panels.some(panel=>{for(const state of this.forks.values())if(state.panelId===panel.id&&!state.completed)return!0;return!1})?!0:this.showConfirmDialog("Some panels haven\u2019t finished yet. Are you sure you want to close them?")}showConfirmDialog(message){return new Promise(resolve=>{if(!this.rootElement){resolve(!0);return}const overlay=document.createElement("div");overlay.className="mb-adapt mb-adapt__confirm-overlay",this.darkMode&&overlay.classList.add("mb-adapt--dark");const card=document.createElement("div");card.className="mb-adapt__confirm-card";const text=document.createElement("p");text.className="mb-adapt__confirm-text",text.textContent=message,card.appendChild(text);const buttons=document.createElement("div");buttons.className="mb-adapt__confirm-buttons";const cancelBtn=document.createElement("button");cancelBtn.className="mb-adapt__confirm-btn mb-adapt__confirm-btn--cancel",cancelBtn.textContent="Cancel";const confirmBtn=document.createElement("button");confirmBtn.className="mb-adapt__confirm-btn mb-adapt__confirm-btn--confirm",confirmBtn.textContent="Close",buttons.appendChild(cancelBtn),buttons.appendChild(confirmBtn),card.appendChild(buttons),overlay.appendChild(card),document.body.appendChild(overlay);const cleanup=result=>{overlay.remove(),resolve(result)};cancelBtn.addEventListener("click",()=>cleanup(!1)),confirmBtn.addEventListener("click",()=>cleanup(!0)),overlay.addEventListener("click",e=>{e.target===overlay&&cleanup(!1)})})}async destroy(){this.destroyed=!0,this.mainCloseTimer&&(clearTimeout(this.mainCloseTimer),this.mainCloseTimer=null);for(const state of this.forks.values())state.closeTimer&&(clearTimeout(state.closeTimer),state.closeTimer=null);this.beforeUnloadHandler&&(window.removeEventListener("beforeunload",this.beforeUnloadHandler),this.beforeUnloadHandler=null),this.resizeObserver?.disconnect(),this.resizeObserver=null,this.capWidgetInstance?.destroy(),this.capWidgetInstance=null,this.minimizeManager?.dispose(),this.minimizeManager=null,this.sessionToken&&!this.loadState()&&!this.sessionTerminated&&this.client.stop(this.sessionToken).catch(()=>{}),await this.client.unsubscribe(),this.messageHandler&&window.removeEventListener("message",this.messageHandler),this.panelManager&&(this.panelManager.dispose(),this.panelManager=null),this.rootElement?.parentNode?.removeChild(this.rootElement),this.mainUrl=null,this.mainToken=void 0,this.forks.clear(),this.components.clear(),this.forkPanelHeights.clear(),this.forkGroupActions.clear(),this.floatingToolbars.clear(),this.sessionToken=null,this.lastForkActive=null,this.rootElement=null,this.messageHandler=null,this.statusMessageElement=null,this.minimizedTabsContainer=null}showStatusMessage(text,kind="error"){if(!this.rootElement)return;this.removeStatusMessage();const mainComponent=this.components.get(MAIN_PANEL_ID);mainComponent&&mainComponent.hide(),this.statusMessageElement=document.createElement("div"),this.statusMessageElement.className=this.options.classNames?.statusMessage??"mb-adapt__status-message";const card=document.createElement("div");card.className=this.options.classNames?.statusCard??"mb-adapt__status-card";const iconWrap=document.createElement("div");iconWrap.className=kind==="stopped"||kind==="expired"?"mb-adapt__status-icon mb-adapt__status-icon--stopped":"mb-adapt__status-icon",iconWrap.innerHTML=kind==="stopped"||kind==="expired"?'<svg viewBox="0 0 24 24" fill="none" stroke="#6b7280" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="6" y="6" width="12" height="12" rx="2"/></svg>':'<svg viewBox="0 0 24 24" fill="none" stroke="#ef4444" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>',card.appendChild(iconWrap);const msg=document.createElement("p");msg.className="mb-adapt__status-text",msg.textContent=text,card.appendChild(msg);const btn=document.createElement("button");btn.className="mb-adapt__status-restart",btn.textContent=this.options.text?.restartButton??"Try again",btn.addEventListener("click",()=>this.newSession()),card.appendChild(btn),this.statusMessageElement.appendChild(card),this.rootElement.appendChild(this.statusMessageElement)}removeStatusMessage(){this.statusMessageElement&&(this.statusMessageElement.remove(),this.statusMessageElement=null)}showErrorStatus(error){const adaptError=this.classifyError(error),overlayKind=adaptError.kind==="expired"?"expired":"error";this.clearState(),this.clearAllForks(),this.showStatusMessage(adaptError.message,overlayKind),this.options.onError?.(adaptError)}isExpiredTokenError(error){return error instanceof ConnectError&&error.code===Code.PermissionDenied&&error.message.toLowerCase().includes("expired")}getErrorMessage(error){const text=this.options.text,fallback=text?.error??"Something went wrong. Please try again later.";if(error instanceof ConnectError){if(this.isExpiredTokenError(error))return text?.sessionExpired??"Your session has expired.";switch(error.code){case Code.ResourceExhausted:return text?.resourceExhausted??"This automation is currently at capacity. Please try again later.";case Code.NotFound:return error.message.toLowerCase().includes("session not found")?text?.sessionNotFound??"This session has timed out or been stopped.":text?.notFound??"This automation could not be found.";case Code.PermissionDenied:case Code.Unauthenticated:return text?.permissionDenied??"You don't have permission to run this automation.";default:return fallback}}return fallback}classifyError(error){const message=this.getErrorMessage(error);if(error instanceof ConnectError){if(this.isExpiredTokenError(error))return{kind:"expired",message,retriable:!1,cause:error};switch(error.code){case Code.ResourceExhausted:return{kind:"capacity",message,retriable:!0,cause:error};case Code.NotFound:return error.message.toLowerCase().includes("session not found")?{kind:"session_not_found",message,retriable:!1,cause:error}:{kind:"not_found",message,retriable:!1,cause:error};case Code.PermissionDenied:case Code.Unauthenticated:return{kind:"auth",message,retriable:!0,cause:error};default:return{kind:"error",message,retriable:!1,cause:error}}}return{kind:"error",message,retriable:!1,cause:error}}};_AdaptWebClient._capWidgetClass=null;let AdaptWebClient=_AdaptWebClient;export{AdaptAutomationElement,AdaptWebClient,FloatingToolbar2 as FloatingToolbar,ForkGroupActions2 as ForkGroupActions,IframePanelComponent2 as IframePanelComponent,MinimizeManager2 as MinimizeManager,PanelManager2 as PanelManager,clearPersistedState,configure,createConnectClient,resetConfig,resolveTheme2 as resolveTheme};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AdaptTheme } from "./theme.js";
|
|
2
|
-
import type { AdaptWebClientOptions, CapWidgetOptions, Output, PersistOptions, SignalValue, StatusJson, StatusText } from "./types.js";
|
|
2
|
+
import type { AdaptError, AdaptWebClientOptions, CapWidgetOptions, Output, PersistOptions, SignalValue, StatusJson, StatusText } from "./types.js";
|
|
3
3
|
/**
|
|
4
4
|
* `<adapt-automation>` custom element for embedding Adapt automations.
|
|
5
5
|
*
|
|
@@ -42,6 +42,7 @@ export declare class AdaptAutomationElement extends BaseElement {
|
|
|
42
42
|
onSessionCallback: ((status: StatusJson, fork?: string) => void) | undefined;
|
|
43
43
|
onOutputCallback: ((output: Output) => void) | undefined;
|
|
44
44
|
onForkActiveCallback: ((active: boolean) => void) | undefined;
|
|
45
|
+
onErrorCallback: ((error: AdaptError) => void) | undefined;
|
|
45
46
|
get automationId(): string | null;
|
|
46
47
|
set automationId(v: string | null);
|
|
47
48
|
get darkMode(): boolean;
|
package/dist/types/core.d.ts
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* ```
|
|
11
11
|
*/
|
|
12
12
|
export { AdaptWebClient as WebClient } from "./index.js";
|
|
13
|
-
export type { AdaptTheme, AdaptWebClientOptions, CapWidgetI18n, CapWidgetOptions, ChallengeInfo, ForkDisplay, Output, PersistOptions, RedeemedChallenge, SignalValue, StatusJson, StatusText, } from "./types.js";
|
|
13
|
+
export type { AdaptError, AdaptErrorKind, AdaptTheme, AdaptWebClientOptions, CapWidgetI18n, CapWidgetOptions, ChallengeInfo, ForkDisplay, Output, PersistOptions, RedeemedChallenge, SignalValue, StatusJson, StatusText, } from "./types.js";
|
|
14
14
|
export { resolveTheme } from "./theme.js";
|
|
15
15
|
export type { SignalData } from "@mochabug/adapt-core";
|
|
16
16
|
export { createConnectClient } from "@mochabug/adapt-core/connect";
|
package/dist/types/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { createConnectClient } from "@mochabug/adapt-core/connect";
|
|
|
3
3
|
import { IframePanelComponent, type IframePanelHost } from "./panel-setup.js";
|
|
4
4
|
import { type AdaptTheme } from "./theme.js";
|
|
5
5
|
import type { AdaptWebClientOptions } from "./types.js";
|
|
6
|
-
export type { AdaptTheme, AdaptWebClientOptions, CapWidgetI18n, CapWidgetOptions, ChallengeInfo, ForkDisplay, Output, PersistOptions, RedeemedChallenge, SignalValue, StatusJson, StatusText, } from "./types.js";
|
|
6
|
+
export type { AdaptError, AdaptErrorKind, AdaptTheme, AdaptWebClientOptions, CapWidgetI18n, CapWidgetOptions, ChallengeInfo, ForkDisplay, Output, PersistOptions, RedeemedChallenge, SignalValue, StatusJson, StatusText, } from "./types.js";
|
|
7
7
|
export { resolveTheme } from "./theme.js";
|
|
8
8
|
export type { SignalData } from "@mochabug/adapt-core";
|
|
9
9
|
export { createConnectClient };
|
|
@@ -83,6 +83,7 @@ export declare class AdaptWebClient implements IframePanelHost {
|
|
|
83
83
|
/** Read --mb-adapt-responsive-hysteresis from the root element, falling back to default. */
|
|
84
84
|
private get responsiveHysteresis();
|
|
85
85
|
private destroyed;
|
|
86
|
+
private sessionTerminated;
|
|
86
87
|
private removingPanelProgrammatically;
|
|
87
88
|
private lastForkActive;
|
|
88
89
|
private sessionExpiresAt;
|
|
@@ -243,4 +244,5 @@ export declare class AdaptWebClient implements IframePanelHost {
|
|
|
243
244
|
private showErrorStatus;
|
|
244
245
|
private isExpiredTokenError;
|
|
245
246
|
private getErrorMessage;
|
|
247
|
+
private classifyError;
|
|
246
248
|
}
|
package/dist/types/types.d.ts
CHANGED
|
@@ -402,6 +402,23 @@ export interface AdaptWebClientOptions {
|
|
|
402
402
|
* @param active - Whether a fork is visually active
|
|
403
403
|
*/
|
|
404
404
|
onForkActive?: (active: boolean) => void;
|
|
405
|
+
/**
|
|
406
|
+
* Callback invoked when the automation encounters an error.
|
|
407
|
+
* Receives a structured error with classification, message, and retriability.
|
|
408
|
+
* Fires for both init-phase errors (e.g. invalid inheritToken) and streaming errors.
|
|
409
|
+
*
|
|
410
|
+
* @example
|
|
411
|
+
* ```typescript
|
|
412
|
+
* onError: (error) => {
|
|
413
|
+
* if (error.retriable) {
|
|
414
|
+
* console.log('Retriable error:', error.kind, error.message);
|
|
415
|
+
* } else {
|
|
416
|
+
* console.error('Fatal error:', error.kind, error.message);
|
|
417
|
+
* }
|
|
418
|
+
* }
|
|
419
|
+
* ```
|
|
420
|
+
*/
|
|
421
|
+
onError?: (error: AdaptError) => void;
|
|
405
422
|
/**
|
|
406
423
|
* Custom CSS class names to override default styling.
|
|
407
424
|
* All properties are optional. Unspecified classes use defaults.
|
|
@@ -511,3 +528,10 @@ export interface StatusText {
|
|
|
511
528
|
/** Label for the restart/try-again button on status cards. Default: `"Try again"` */
|
|
512
529
|
restartButton?: string;
|
|
513
530
|
}
|
|
531
|
+
export type AdaptErrorKind = 'auth' | 'expired' | 'not_found' | 'session_not_found' | 'capacity' | 'error';
|
|
532
|
+
export interface AdaptError {
|
|
533
|
+
kind: AdaptErrorKind;
|
|
534
|
+
message: string;
|
|
535
|
+
retriable: boolean;
|
|
536
|
+
cause?: unknown;
|
|
537
|
+
}
|
|
@@ -4324,7 +4324,7 @@ var MbAdapt = (() => {
|
|
|
4324
4324
|
// src/cap-adapter.ts
|
|
4325
4325
|
if (typeof window !== "undefined" && true && !window.CAP_CUSTOM_WASM_URL) {
|
|
4326
4326
|
window.CAP_CUSTOM_WASM_URL = new URL(
|
|
4327
|
-
"https://cdn.mochabug.com/adapt/web/1.0.1-rc.
|
|
4327
|
+
"https://cdn.mochabug.com/adapt/web/1.0.1-rc.18/cap_wasm.js",
|
|
4328
4328
|
window.location.href
|
|
4329
4329
|
).href;
|
|
4330
4330
|
}
|
|
Binary file
|