UNPKG

@react-native/debugger-frontend

Version:
2 lines (1 loc) 5.78 kB
import*as e from"../../core/sdk/sdk.js";const t="main",i="__FUSEBOX_REACT_DEVTOOLS_DISPATCHER__";class n extends e.SDKModel.SDKModel{domainToListeners=new Map;messagingBindingName=null;enabled=!1;fuseboxDispatcherIsInitialized=!1;domainToMessageQueue=new Map;dispose(){this.domainToListeners.clear(),this.domainToMessageQueue.clear();const t=this.target().model(e.RuntimeModel.RuntimeModel);t?.removeEventListener(e.RuntimeModel.Events.BindingCalled,this.bindingCalled,this),t?.removeEventListener(e.RuntimeModel.Events.ExecutionContextCreated,this.onExecutionContextCreated,this),t?.removeEventListener(e.RuntimeModel.Events.ExecutionContextDestroyed,this.onExecutionContextDestroyed,this)}bindingCalled(e){if(null===this.messagingBindingName||e.data.name!==this.messagingBindingName)return;const t=e.data.payload;let i=null;try{i=JSON.parse(t)}catch(e){throw new Error("Failed to parse bindingCalled event payload",{cause:e})}if(i){const e=i.domain;if(this.fuseboxDispatcherIsInitialized){if(!this.isDomainMessagesQueueEmpty(e))throw new Error(`Attempted to send a message to domain ${e} while queue is not empty`);this.dispatchMessageToDomainEventListeners(e,i.message)}else this.queueMessageForDomain(e,i.message)}}queueMessageForDomain(e,t){let i=this.domainToMessageQueue.get(e);i||(i=[],this.domainToMessageQueue.set(e,i)),i.push(t)}flushOutDomainMessagesQueues(){for(const[e,t]of this.domainToMessageQueue.entries())if(0!==t.length){for(const i of t)this.dispatchMessageToDomainEventListeners(e,i);t.splice(0,t.length)}}isDomainMessagesQueueEmpty(e){const t=this.domainToMessageQueue.get(e);return void 0===t||0===t.length}subscribeToDomainMessages(e,t){let i=this.domainToListeners.get(e);i||(i=new Set,this.domainToListeners.set(e,i)),i.add(t)}unsubscribeFromDomainMessages(e,t){const i=this.domainToListeners.get(e);i&&i.delete(t)}dispatchMessageToDomainEventListeners(e,t){const i=this.domainToListeners.get(e);if(!i)return;const n=[];for(const e of i)try{e(t)}catch(e){n.push(e)}if(n.length>0)throw new AggregateError(n,`Error occurred in ReactDevToolsBindingsModel while calling event listeners for domain ${e}`)}async initializeDomain(t){const n=this.target().model(e.RuntimeModel.RuntimeModel);if(!n)throw new Error(`Failed to initialize domain ${t} for ReactDevToolsBindingsModel: runtime model is not available`);await n.agent.invoke_evaluate({expression:`void ${i}.initializeDomain('${t}')`})}async sendMessage(t,n){if(!this.fuseboxDispatcherIsInitialized)return;const o=this.target().model(e.RuntimeModel.RuntimeModel);if(!o)throw new Error(`Failed to send message from ReactDevToolsBindingsModel for domain ${t}: runtime model is not available`);const s=JSON.stringify(n);await o.agent.invoke_evaluate({expression:`${i}.sendMessage('${t}', '${s}')`})}async enable(){if(this.enabled)throw new Error("ReactDevToolsBindingsModel is already enabled");const t=this.target().model(e.RuntimeModel.RuntimeModel);if(!t)throw new Error("Failed to enable ReactDevToolsBindingsModel: runtime model is not available");await this.waitForFuseboxDispatcherToBeInitialized().then((()=>t.agent.invoke_evaluate({expression:`${i}.BINDING_NAME`}))).then((e=>{if(e.exceptionDetails)throw new Error("Failed to get binding name for ReactDevToolsBindingsModel on a global: "+e.exceptionDetails.text);if(null===e.result.value||void 0===e.result.value)throw new Error("Failed to get binding name for ReactDevToolsBindingsModel on a global: returned value is "+String(e.result.value));if(""===e.result.value)throw new Error("Failed to get binding name for ReactDevToolsBindingsModel on a global: returned value is an empty string");return e.result.value})).then((i=>(this.messagingBindingName=i,t.addEventListener(e.RuntimeModel.Events.BindingCalled,this.bindingCalled,this),t.agent.invoke_addBinding({name:i})))).then((e=>{const t=e.getError();if(t)throw new Error("Failed to add binding for ReactDevToolsBindingsModel: "+t);this.enabled=!0,this.initializeExecutionContextListeners()}))}isEnabled(){return this.enabled}initializeExecutionContextListeners(){const t=this.target().model(e.RuntimeModel.RuntimeModel);if(!t)throw new Error("Failed to initialize execution context listeners for ReactDevToolsBindingsModel: runtime model is not available");t.addEventListener(e.RuntimeModel.Events.ExecutionContextCreated,this.onExecutionContextCreated,this),t.addEventListener(e.RuntimeModel.Events.ExecutionContextDestroyed,this.onExecutionContextDestroyed,this)}onExecutionContextCreated({data:e}){e.name===t&&this.waitForFuseboxDispatcherToBeInitialized().then((()=>{this.dispatchEventToListeners("BackendExecutionContextCreated"),this.flushOutDomainMessagesQueues()})).catch((e=>this.dispatchEventToListeners("BackendExecutionContextUnavailable",e.message)))}onExecutionContextDestroyed({data:e}){e.name===t&&(this.fuseboxDispatcherIsInitialized=!1,this.dispatchEventToListeners("BackendExecutionContextDestroyed"))}async waitForFuseboxDispatcherToBeInitialized(t=1){if(t>=20)throw new Error("Failed to wait for initialization: it took too long");const n=this.target().model(e.RuntimeModel.RuntimeModel);if(!n)throw new Error("Failed to wait for React DevTools dispatcher initialization: runtime model is not available");await n.agent.invoke_evaluate({expression:`globalThis.${i} != undefined`,returnByValue:!0}).then((e=>{if(e.exceptionDetails)throw new Error("Failed to wait for React DevTools dispatcher initialization: "+e.exceptionDetails.text);if(!1===e.result.value)return new Promise((e=>setTimeout(e,250))).then((()=>this.waitForFuseboxDispatcherToBeInitialized(t+1)));this.fuseboxDispatcherIsInitialized=!0}))}}e.SDKModel.SDKModel.register(n,{capabilities:4,autostart:!1});var o=Object.freeze({__proto__:null,ReactDevToolsBindingsModel:n});export{o as ReactDevToolsBindingsModel};