@devbookhq/sdk
Advanced tools
Comparing version 0.1.0 to 0.1.2
@@ -30,2 +30,5 @@ import { Env } from './constants'; | ||
private readonly contextID; | ||
private _isDestroyed; | ||
private get isDestroyed(); | ||
private set isDestroyed(value); | ||
private _isEnvReady; | ||
@@ -39,4 +42,4 @@ private get isEnvReady(); | ||
/** | ||
* Current status of this `Devbook`'s connection. | ||
*/ | ||
* Current status of this `Devbook`'s connection. | ||
*/ | ||
get status(): DevbookStatus; | ||
@@ -86,4 +89,8 @@ private set status(value); | ||
runCode(code: string): void; | ||
/** | ||
* Disconnect this Devbook from the VM. | ||
*/ | ||
destroy(): void; | ||
private updateStatus; | ||
} | ||
export default Devbook; |
@@ -1,2 +0,2 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react");exports.Env=void 0,(exports.Env||(exports.Env={})).NodeJS="nodejs-v16";const n={"nodejs-v16":{id:"nodejs-v16",image:"us-central1-docker.pkg.dev/devbookhq/devbook-runner-templates/nodejs-v16:latest",root_dir:"/home/runner",code_cells_dir:"/home/runner/src",toCommand:e=>`node -e "${e}"`}};class t{constructor(e,n=!1){this.logID=e,this.isEnabled=n}id(){return"function"==typeof this.logID?this.logID():this.logID}log(...e){this.isEnabled&&console.log(`[36m[${this.id()}][0m`,...e)}warn(...e){this.isEnabled&&console.warn(`[36m[${this.id()}][0m`,...e)}error(...e){console.error(`[31m[${this.id()} ERROR][0m`,...e)}} | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react");exports.Env=void 0,(exports.Env||(exports.Env={})).NodeJS="nodejs-v16";const t={"nodejs-v16":{id:"nodejs-v16",image:"us-central1-docker.pkg.dev/devbookhq/devbook-runner-templates/nodejs-v16:latest",root_dir:"/home/runner",code_cells_dir:"/home/runner/src",toCommand:e=>`node -e "${e}"`}};class n{constructor(e,t=!1){this.logID=e,this.isEnabled=t}id(){return"function"==typeof this.logID?this.logID():this.logID}log(...e){this.isEnabled&&console.log(`[36m[${this.id()}][0m`,...e)}warn(...e){this.isEnabled&&console.warn(`[36m[${this.id()}][0m`,...e)}error(...e){console.error(`[31m[${this.id()} ERROR][0m`,...e)}} | ||
/*! ***************************************************************************** | ||
@@ -15,3 +15,3 @@ Copyright (c) Microsoft Corporation. | ||
PERFORMANCE OF THIS SOFTWARE. | ||
***************************************************************************** */function s(e,n,t,s){return new(t||(t=Promise))((function(i,o){function r(e){try{l(s.next(e))}catch(e){o(e)}}function a(e){try{l(s.throw(e))}catch(e){o(e)}}function l(e){var n;e.done?i(e.value):(n=e.value,n instanceof t?n:new t((function(e){e(n)}))).then(r,a)}l((s=s.apply(e,n||[])).next())}))}function i(e){return new Promise((n=>setTimeout(n,e)))}var o,r,a;!function(e){e.Error="Runner.Error"}(o||(o={})),function(e){e.Start="RunningEnvironment.Start",e.StartAck="RunningEnvironment.StartAck",e.Eval="RunningEnvironment.Eval",e.FSEventCreate="RunningEnvironment.FSEventCreate",e.FSEventRemove="RunningEnvironment.FSEventRemove",e.FSEventWrite="RunningEnvironment.FSEventWrite",e.CreateDir="RunningEnvironment.CreateDir",e.ListDir="RunningEnvironment.ListDir",e.WriteFile="RunningEnvironment.WriteFile",e.GetFile="RunningEnvironment.GetFile",e.RemoveFile="RunningEnvironment.RemoveFile",e.DirContent="RunningEnvironment.DirContent",e.FileContent="RunningEnvironment.FileContent",e.Stdout="RunningEnvironment.Stdout",e.Stderr="RunningEnvironment.Stderr",e.ExecCmd="RunningEnvironment.ExecCmd",e.KillCmd="RunningEnvironment.KillCmd",e.ListRunningCmds="RunningEnvironment.ListRunningCmds",e.CmdOut="RunningEnvironment.CmdOut",e.CmdExit="RunningEnvironment.CmdExit",e.RunningCmds="RunningEnvironment.RunningCmds"}(r||(r={})),function(e){e.Error="CodeCell.Error"}(a||(a={}));const l={Runner:o,RunningEnvironment:r,CodeCell:a};class c{constructor(){this.url="wss://orchestrator.usedevbook.com",this.logger=new t("WebSocketConnection"),this.handlers=[]}get state(){var e;return null===(e=this.client)||void 0===e?void 0:e.readyState}get isClosed(){if(void 0!==this.client)return this.client.readyState===this.client.CLOSED}get isClosing(){if(void 0!==this.client)return this.client.readyState===this.client.CLOSING}get isOpen(){if(void 0!==this.client)return this.client.readyState===this.client.OPEN}get isConnecting(){if(void 0!==this.client)return this.client.readyState===this.client.CONNECTING}subscribeHandler(e){return this.handlers.push(e),()=>{this.handlers=this.handlers.filter((n=>n!==e))}}connect(e){(!this.client||this.client.readyState!==this.client.CONNECTING&&this.client.readyState!==this.client.OPEN)&&(e||this.sessionID?(e?(this.logger.log(`Will try to connect to session "${e}"`),this.sessionID=e):!e&&this.sessionID&&this.logger.log(`Will try to connect to previous session "${this.sessionID}"`),this.client=new WebSocket(`${this.url}/session/ws/${this.sessionID}`),this.client.onopen=()=>this.handleOpen(),this.client.onmessage=e=>{this.logger.log("Received (raw)",{msg:e}),this.handleMessage(e)},this.client.onerror=e=>this.handleError(e),this.client.onclose=e=>this.handleClose(e)):this.logger.error("Cannot connect, no session ID passed to the function and no session ID saved from the previous session"))}send(e){this.client&&this.client.readyState===this.client.OPEN?(this.logger.log("Send",e),this._send(e)):this.logger.warn("Trying to send a message while not being in the `OPEN` state or without established connection, message will be discarded",e)}close(){var e;this.logger.log("Closing connection"),null===(e=this.client)||void 0===e||e.close(1e3)}handleOpen(){var e;this.logger.log("Connection opened",{readyState:null===(e=this.client)||void 0===e?void 0:e.readyState}),this.handlers.forEach((e=>e.onOpen()))}_send(e){var n,t;null===(n=this.client)||void 0===n||n.send((t=e,JSON.stringify(t,(()=>{const e=new WeakSet;return(n,t)=>{if("object"==typeof t&&null!==t){if(e.has(t))return;e.add(t)}return t}})(),2)))}handleClose(e){return s(this,void 0,void 0,(function*(){this.logger.log("Connection closed",e),this.handlers.forEach((e=>e.onClose())),this.logger.log("Will try to reconnect in 3s"),yield i(3e3),this.connect()}))}handleError(e){var n;this.logger.error("Connection error",e),null===(n=this.client)||void 0===n||n.close()}handleMessage(e){if(!e.data)return void this.logger.error("Message has empty data field",e);const n=JSON.parse(e.data);if(!n.type)return void this.logger.error("Message has no type",n);const t=n;Object.values(l.RunningEnvironment).includes(t.type)||Object.values(l.Runner).includes(t.type)||Object.values(l.CodeCell).includes(t.type)?t.type!==l.Runner.Error?(this.logger.log("Received (parsed)",t),this.handlers.forEach((e=>e.onMessage(t)))):this.logger.error("Runner error",t):this.logger.error('Message "type" field has unexpected value',t)}}var d,h;!function(e){e.Ok="Ok",e.Terminated="Terminated"}(d||(d={}));class u{constructor(e,n=new Date){this.id=e,this.lastPing=n,this.logger=new t("RunnerSession"),this.url="https://orchestrator.usedevbook.com"}ping(){return s(this,void 0,void 0,(function*(){this.logger.log(`Pinging session "${this.id}"`);const e=JSON.stringify({sessionID:this.id});try{const n=yield fetch(`${this.url}/session/ping`,{method:"POST",headers:{"Content-Type":"application/json"},body:e}),t=yield n.json();if(!n.ok)throw this.logger.error(n.headers,t),new Error("Non-OK response when trying to ping active Runner session");if(t.status===d.Terminated)throw new Error(`[keepAlive]: Session '${this.id}' is terminated`);this.lastPing=new Date}catch(e){throw this.logger.error(e),new Error("Failed to ping active Runner session")}}))}}!function(e){e.Connected="Connected",e.Connecting="Connecting",e.Disconnected="Disconnected"}(h||(h={}));class g{constructor(e){this.conn=e,this.logger=new t("SessionManager"),this.url="https://orchestrator.usedevbook.com",this.isGettingSessionActive=!1,this.status=h.Disconnected,this.logger.log("Initialize"),this.getSession()}get cachedSessionID(){return sessionStorage.getItem("dbk_sdk_session_id")}set cachedSessionID(e){null===e?(this.logger.log("Cleared last sessionID"),sessionStorage.removeItem("dbk_sdk_session_id")):(this.logger.log(`Saved sessionID "${e}" as last sessionID`),sessionStorage.setItem("dbk_sdk_session_id",e))}reset(){this.logger.log("Reset"),this.status=h.Disconnected,this.cachedSessionID=null,this.conn.close(),this.session=void 0}getSession(){var e;return s(this,void 0,void 0,(function*(){if(!this.isGettingSessionActive)for(this.isGettingSessionActive=!0;;){this.status=h.Connecting;try{const n=this.cachedSessionID?`${this.url}/session/${this.cachedSessionID}`:`${this.url}/session`;this.cachedSessionID?this.logger.log(`Restoring old Runner session "${this.cachedSessionID}"`):this.logger.log("Acquiring new Runner session");const t=yield fetch(n),s=yield t.json();if(!t.ok){this.logger.error("Non-OK response when trying to ping active Runner session. Will try again in 3s",t.headers,s),yield i(3e3);continue}for(this.session=new u(s.sessionID),this.logger.log(`Acquired session "${this.session.id}"`),this.cachedSessionID=this.session.id,this.status=h.Connected,this.conn.connect(this.session.id),this.logger.log(`Started pinging session "${this.session.id}"`);this.session;)try{yield this.session.ping(),yield i(5e3)}catch(e){this.logger.error(`Failed to ping session "${this.session.id}"`,e);break}this.logger.log(`Stopped pinging session "${null===(e=this.session)||void 0===e?void 0:e.id}"`),this.session=void 0,this.status=h.Disconnected,this.conn.close()}catch(e){this.logger.error("Failed to acquire Runner session. Will try again in 3s",e),yield i(3e3)}}}))}}function v(e){return function(e){const n=Array.from(e).reduce(((e,n)=>0|31*e+n.charCodeAt(0)),0);return("0000000"+(n>>>0).toString(16)).slice(-8)}(e)}class m{constructor(e,t){this.contextID=e,this.templateID=t,this.isReady=!1,this.id=`${e}_${v(t)}`,this.template=n[this.templateID]}}function p(e,{environmentID:n,template:t}){const s={type:l.RunningEnvironment.Start,payload:{environmentID:n,template:t}};e.send(s)}class C{constructor(e){this.opts=e,this.envs=[],this.logger=new t("EvaluationContext",e.debug),this.unsubscribeConnHandler=this.opts.conn.subscribeHandler({onOpen:this.handleConnectionOpen.bind(this),onMessage:this.handleConnectionMessage.bind(this),onClose:this.handleConnectionClose.bind(this)}),this.opts.conn.isOpen&&this.handleConnectionOpen(),this.opts.conn.isClosed&&this.handleConnectionClose()}get contextID(){return this.opts.contextID}handleConnectionOpen(){var e,n;this.restart(),null===(n=(e=this.opts).onSessionChange)||void 0===n||n.call(e,{status:h.Connected})}handleConnectionClose(){var e,n;null===(n=(e=this.opts).onSessionChange)||void 0===n||n.call(e,{status:h.Connecting})}restart(){var e;return null===(e=this.logger)||void 0===e||e.log("Restart - session:",this.opts.conn.sessionID),this.envs.forEach((e=>{e.isReady=!1,p(this.opts.conn,{environmentID:e.id,template:e.template})}))}destroy(){var e;null===(e=this.logger)||void 0===e||e.log("Destroy"),this.envs=[],this.unsubscribeConnHandler()}handleConnectionMessage(e){var n,t;switch(null===(n=this.logger)||void 0===n||n.log("Handling message from remote Runner",{message:e}),e.type){case l.RunningEnvironment.StartAck:{const n=e;this.vmenv_handleStartAck(n.payload);break}case l.RunningEnvironment.CmdOut:{const n=e;this.vmenv_handleCmdOut(n.payload);break}default:null===(t=this.logger)||void 0===t||t.warn("Unknown message type",{message:e})}}deleteRunningEnvironment({templateID:e}){var n;null===(n=this.logger)||void 0===n||n.log('Handling "DeleteEnvironment"',{templateID:e}),this.envs=this.envs.filter((n=>n.templateID!==e))}createRunningEnvironment({templateID:e}){var n,t,s;null===(n=this.logger)||void 0===n||n.log('Handling "CreateEnvironment"',{templateID:e});const i=this.envs.find((n=>n.templateID===e));if(i)return i;const o=new m(this.contextID,e);return this.envs=[...this.envs,o],p(this.opts.conn,{environmentID:o.id,template:o.template}),null===(s=(t=this.opts).onEnvChange)||void 0===s||s.call(t,o),o}vmenv_handleStartAck(e){var n,t,s,i;null===(n=this.logger)||void 0===n||n.log('[vmenv] Handling "StartAck"',{payload:e});const o=this.envs.find((n=>n.id===e.environmentID));o?(o.isReady=!0,null===(i=(s=this.opts).onEnvChange)||void 0===i||i.call(s,o)):null===(t=this.logger)||void 0===t||t.warn("Environment not found",{payload:e})}vmenv_handleCmdOut(e){var n,t,s;null===(n=this.logger)||void 0===n||n.log('[vmenv] Handling "CmdOut"',e),null===(s=(t=this.opts).onCmdOut)||void 0===s||s.call(t,e)}executeCommand({templateID:e,executionID:n,command:t}){var s,i,o;null===(s=this.logger)||void 0===s||s.log("Exec shell code cell",{templateID:e,executionID:n,command:t});const r=this.envs.find((n=>n.templateID===e));r?r.isReady?function(e,{environmentID:n,executionID:t,command:s}){const i={type:l.RunningEnvironment.ExecCmd,payload:{environmentID:n,executionID:t,command:s}};e.send(i)}(this.opts.conn,{environmentID:r.id,executionID:n,command:t}):null===(o=this.logger)||void 0===o||o.error("Environment is not ready",{templateID:e,executionID:n,command:t}):null===(i=this.logger)||void 0===i||i.error("Environment not found",{templateID:e,executionID:n,command:t})}}class D{constructor(){this.logger=new t("Runner"),this.conn=new c,this.sessManager=new g(this.conn)}static get obj(){return D._obj||(D._obj=new D)}get session(){return this.sessManager.session}get status(){return this.sessManager.status}reset(){this.logger.log("Reset"),this.sessManager.reset()}createContext(e){return new C(Object.assign(Object.assign({},e),{conn:this.conn}))}__debug__loadNewSession(){this.logger.log("__debug__loadNewSession"),this.sessManager.reset()}}const S=(E="1234567890abcdefghijklmnopqrstuvwxyz",y=6,()=>{let e="",n=y;for(;n--;)e+=E[Math.random()*E.length|0];return e});var E,y,R;exports.DevbookStatus=void 0,(R=exports.DevbookStatus||(exports.DevbookStatus={}))[R.Disconnected=0]="Disconnected",R[R.Connecting=1]="Connecting",R[R.Connected=2]="Connected";class I{constructor(e){this.opts=e,this._isEnvReady=!1,this._sessionStatus=h.Disconnected,this._status=exports.DevbookStatus.Disconnected;const n="default";this.contextID=n;const t=S();this.executionID=t;const s=e=>this.isEnvReady=e,i=e=>this.sessionStatus=e;this.context=D.obj.createContext({debug:e.debug,contextID:n,onEnvChange(e){s(e.isReady)},onSessionChange({status:e}){i(e)},onCmdOut(n){var s,i;n.executionID===t&&(void 0!==n.stdout&&(null===(s=e.onStdout)||void 0===s||s.call(e,n.stdout)),void 0!==n.stderr&&(null===(i=e.onStderr)||void 0===i||i.call(e,n.stderr)))}}),this.context.createRunningEnvironment({templateID:e.env})}get isEnvReady(){return this._isEnvReady}set isEnvReady(e){this._isEnvReady=e,this.updateStatus()}get sessionStatus(){return this._sessionStatus}set sessionStatus(e){this._sessionStatus=e,this.updateStatus()}get status(){return this._status}set status(e){var n,t;this._status=e,null===(t=(n=this.opts).onStatusChange)||void 0===t||t.call(n,e)}runCmd(e){this.context.executeCommand({templateID:this.opts.env,executionID:this.executionID,command:e})}runCode(e){const t=n[this.opts.env].toCommand(e);this.runCmd(t)}updateStatus(){let e;switch(this.sessionStatus){case h.Disconnected:e=exports.DevbookStatus.Disconnected;break;case h.Connecting:e=exports.DevbookStatus.Connecting;break;case h.Connected:if(!this.isEnvReady){e=exports.DevbookStatus.Connecting;break}e=exports.DevbookStatus.Connected}this.status=e}}exports.Devbook=I,exports.useDevbook=function({env:n,debug:t}){const[s,i]=e.useState(),[o,r]=e.useState(exports.DevbookStatus.Disconnected),[a,l]=e.useState([]),[c,d]=e.useState([]),h=e.useCallback((e=>{s&&(d([]),l([]),s.runCmd(e))}),[s]),u=e.useCallback((e=>{s&&(d([]),l([]),s.runCode(e))}),[s]);return e.useEffect((function(){const e=new I({debug:t,env:n,onStatusChange(e){r(e)},onStderr(e){l((n=>[...n,e]))},onStdout(e){d((n=>[...n,e]))}});d([]),l([]),i(e)}),[n,t]),{stderr:a,stdout:c,runCmd:h,runCode:u,status:o}}; | ||
***************************************************************************** */function s(e,t,n,s){return new(n||(n=Promise))((function(i,o){function r(e){try{l(s.next(e))}catch(e){o(e)}}function a(e){try{l(s.throw(e))}catch(e){o(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(r,a)}l((s=s.apply(e,t||[])).next())}))}function i(e){return new Promise((t=>setTimeout(t,e)))}var o,r,a;!function(e){e.Error="Runner.Error"}(o||(o={})),function(e){e.Start="RunningEnvironment.Start",e.StartAck="RunningEnvironment.StartAck",e.Eval="RunningEnvironment.Eval",e.FSEventCreate="RunningEnvironment.FSEventCreate",e.FSEventRemove="RunningEnvironment.FSEventRemove",e.FSEventWrite="RunningEnvironment.FSEventWrite",e.CreateDir="RunningEnvironment.CreateDir",e.ListDir="RunningEnvironment.ListDir",e.WriteFile="RunningEnvironment.WriteFile",e.GetFile="RunningEnvironment.GetFile",e.RemoveFile="RunningEnvironment.RemoveFile",e.DirContent="RunningEnvironment.DirContent",e.FileContent="RunningEnvironment.FileContent",e.Stdout="RunningEnvironment.Stdout",e.Stderr="RunningEnvironment.Stderr",e.ExecCmd="RunningEnvironment.ExecCmd",e.KillCmd="RunningEnvironment.KillCmd",e.ListRunningCmds="RunningEnvironment.ListRunningCmds",e.CmdOut="RunningEnvironment.CmdOut",e.CmdExit="RunningEnvironment.CmdExit",e.RunningCmds="RunningEnvironment.RunningCmds"}(r||(r={})),function(e){e.Error="CodeCell.Error"}(a||(a={}));const l={Runner:o,RunningEnvironment:r,CodeCell:a};class c{constructor(){this.url="wss://orchestrator.usedevbook.com",this.logger=new n("WebSocketConnection"),this.handlers=[]}get state(){var e;return null===(e=this.client)||void 0===e?void 0:e.readyState}get isClosed(){if(void 0!==this.client)return this.client.readyState===this.client.CLOSED}get isClosing(){if(void 0!==this.client)return this.client.readyState===this.client.CLOSING}get isOpen(){if(void 0!==this.client)return this.client.readyState===this.client.OPEN}get isConnecting(){if(void 0!==this.client)return this.client.readyState===this.client.CONNECTING}subscribeHandler(e){return this.handlers.push(e),()=>{this.handlers=this.handlers.filter((t=>t!==e))}}connect(e){(!this.client||this.client.readyState!==this.client.CONNECTING&&this.client.readyState!==this.client.OPEN)&&(e||this.sessionID?(e?(this.logger.log(`Will try to connect to session "${e}"`),this.sessionID=e):!e&&this.sessionID&&this.logger.log(`Will try to connect to previous session "${this.sessionID}"`),this.client=new WebSocket(`${this.url}/session/ws/${this.sessionID}`),this.client.onopen=()=>this.handleOpen(),this.client.onmessage=e=>{this.logger.log("Received (raw)",{msg:e}),this.handleMessage(e)},this.client.onerror=e=>this.handleError(e),this.client.onclose=e=>this.handleClose(e)):this.logger.error("Cannot connect, no session ID passed to the function and no session ID saved from the previous session"))}send(e){this.client&&this.client.readyState===this.client.OPEN?(this.logger.log("Send",e),this._send(e)):this.logger.warn("Trying to send a message while not being in the `OPEN` state or without established connection, message will be discarded",e)}close(){var e;this.logger.log("Closing connection"),null===(e=this.client)||void 0===e||e.close(1e3)}handleOpen(){var e;this.logger.log("Connection opened",{readyState:null===(e=this.client)||void 0===e?void 0:e.readyState}),this.handlers.forEach((e=>e.onOpen()))}_send(e){var t,n;null===(t=this.client)||void 0===t||t.send((n=e,JSON.stringify(n,(()=>{const e=new WeakSet;return(t,n)=>{if("object"==typeof n&&null!==n){if(e.has(n))return;e.add(n)}return n}})(),2)))}handleClose(e){return s(this,void 0,void 0,(function*(){this.logger.log("Connection closed",e),this.handlers.forEach((e=>e.onClose())),this.logger.log("Will try to reconnect in 3s"),yield i(3e3),this.connect()}))}handleError(e){var t;this.logger.error("Connection error",e),null===(t=this.client)||void 0===t||t.close()}handleMessage(e){if(!e.data)return void this.logger.error("Message has empty data field",e);const t=JSON.parse(e.data);if(!t.type)return void this.logger.error("Message has no type",t);const n=t;Object.values(l.RunningEnvironment).includes(n.type)||Object.values(l.Runner).includes(n.type)||Object.values(l.CodeCell).includes(n.type)?n.type!==l.Runner.Error?(this.logger.log("Received (parsed)",n),this.handlers.forEach((e=>e.onMessage(n)))):this.logger.error("Runner error",n):this.logger.error('Message "type" field has unexpected value',n)}}var d,h;!function(e){e.Ok="Ok",e.Terminated="Terminated"}(d||(d={}));class u{constructor(e,t=new Date){this.id=e,this.lastPing=t,this.logger=new n("RunnerSession"),this.url="https://orchestrator.usedevbook.com"}ping(){return s(this,void 0,void 0,(function*(){this.logger.log(`Pinging session "${this.id}"`);const e=JSON.stringify({sessionID:this.id});try{const t=yield fetch(`${this.url}/session/ping`,{method:"POST",headers:{"Content-Type":"application/json"},body:e}),n=yield t.json();if(!t.ok)throw this.logger.error(t.headers,n),new Error("Non-OK response when trying to ping active Runner session");if(n.status===d.Terminated)throw new Error(`[keepAlive]: Session '${this.id}' is terminated`);this.lastPing=new Date}catch(e){throw this.logger.error(e),new Error("Failed to ping active Runner session")}}))}}!function(e){e.Connected="Connected",e.Connecting="Connecting",e.Disconnected="Disconnected"}(h||(h={}));class g{constructor(e){this.conn=e,this.logger=new n("SessionManager"),this.url="https://orchestrator.usedevbook.com",this.isGettingSessionActive=!1,this.status=h.Disconnected,this.logger.log("Initialize"),this.getSession()}get cachedSessionID(){return sessionStorage.getItem("dbk_sdk_session_id")}set cachedSessionID(e){null===e?(this.logger.log("Cleared last sessionID"),sessionStorage.removeItem("dbk_sdk_session_id")):(this.logger.log(`Saved sessionID "${e}" as last sessionID`),sessionStorage.setItem("dbk_sdk_session_id",e))}reset(){this.logger.log("Reset"),this.status=h.Disconnected,this.cachedSessionID=null,this.conn.close(),this.session=void 0}getSession(){var e;return s(this,void 0,void 0,(function*(){if(!this.isGettingSessionActive)for(this.isGettingSessionActive=!0;;){this.status=h.Connecting;try{const t=this.cachedSessionID?`${this.url}/session/${this.cachedSessionID}`:`${this.url}/session`;this.cachedSessionID?this.logger.log(`Restoring old Runner session "${this.cachedSessionID}"`):this.logger.log("Acquiring new Runner session");const n=yield fetch(t),s=yield n.json();if(!n.ok){this.logger.error("Non-OK response when trying to ping active Runner session. Will try again in 3s",n.headers,s),yield i(3e3);continue}for(this.session=new u(s.sessionID),this.logger.log(`Acquired session "${this.session.id}"`),this.cachedSessionID=this.session.id,this.status=h.Connected,this.conn.connect(this.session.id),this.logger.log(`Started pinging session "${this.session.id}"`);this.session;)try{yield this.session.ping(),yield i(5e3)}catch(e){this.logger.error(`Failed to ping session "${this.session.id}"`,e);break}this.logger.log(`Stopped pinging session "${null===(e=this.session)||void 0===e?void 0:e.id}"`),this.session=void 0,this.status=h.Disconnected,this.conn.close()}catch(e){this.logger.error("Failed to acquire Runner session. Will try again in 3s",e),yield i(3e3)}}}))}}function v(e){return function(e){const t=Array.from(e).reduce(((e,t)=>0|31*e+t.charCodeAt(0)),0);return("0000000"+(t>>>0).toString(16)).slice(-8)}(e)}class m{constructor(e,n){this.contextID=e,this.templateID=n,this.isReady=!1,this.id=`${e}_${v(n)}`,this.template=t[this.templateID]}}function p(e,{environmentID:t,template:n}){const s={type:l.RunningEnvironment.Start,payload:{environmentID:t,template:n}};e.send(s)}class D{constructor(e){this.opts=e,this.envs=[],this.logger=new n("EvaluationContext",e.debug),this.unsubscribeConnHandler=this.opts.conn.subscribeHandler({onOpen:this.handleConnectionOpen.bind(this),onMessage:this.handleConnectionMessage.bind(this),onClose:this.handleConnectionClose.bind(this)}),this.opts.conn.isOpen&&this.handleConnectionOpen(),this.opts.conn.isClosed&&this.handleConnectionClose()}get contextID(){return this.opts.contextID}handleConnectionOpen(){var e,t;this.restart(),null===(t=(e=this.opts).onSessionChange)||void 0===t||t.call(e,{status:h.Connected})}handleConnectionClose(){var e,t;null===(t=(e=this.opts).onSessionChange)||void 0===t||t.call(e,{status:h.Connecting})}restart(){var e;return null===(e=this.logger)||void 0===e||e.log("Restart - session:",this.opts.conn.sessionID),this.envs.forEach((e=>{e.isReady=!1,p(this.opts.conn,{environmentID:e.id,template:e.template})}))}destroy(){var e;null===(e=this.logger)||void 0===e||e.log("Destroy"),this.envs=[],this.unsubscribeConnHandler()}handleConnectionMessage(e){var t,n;switch(null===(t=this.logger)||void 0===t||t.log("Handling message from remote Runner",{message:e}),e.type){case l.RunningEnvironment.StartAck:{const t=e;this.vmenv_handleStartAck(t.payload);break}case l.RunningEnvironment.CmdOut:{const t=e;this.vmenv_handleCmdOut(t.payload);break}default:null===(n=this.logger)||void 0===n||n.warn("Unknown message type",{message:e})}}deleteRunningEnvironment({templateID:e}){var t;null===(t=this.logger)||void 0===t||t.log('Handling "DeleteEnvironment"',{templateID:e}),this.envs=this.envs.filter((t=>t.templateID!==e))}createRunningEnvironment({templateID:e}){var t,n,s;null===(t=this.logger)||void 0===t||t.log('Handling "CreateEnvironment"',{templateID:e});const i=this.envs.find((t=>t.templateID===e));if(i)return i;const o=new m(this.contextID,e);return this.envs=[...this.envs,o],p(this.opts.conn,{environmentID:o.id,template:o.template}),null===(s=(n=this.opts).onEnvChange)||void 0===s||s.call(n,o),o}vmenv_handleStartAck(e){var t,n,s,i;null===(t=this.logger)||void 0===t||t.log('[vmenv] Handling "StartAck"',{payload:e});const o=this.envs.find((t=>t.id===e.environmentID));o?(o.isReady=!0,null===(i=(s=this.opts).onEnvChange)||void 0===i||i.call(s,o)):null===(n=this.logger)||void 0===n||n.warn("Environment not found",{payload:e})}vmenv_handleCmdOut(e){var t,n,s;null===(t=this.logger)||void 0===t||t.log('[vmenv] Handling "CmdOut"',e),null===(s=(n=this.opts).onCmdOut)||void 0===s||s.call(n,e)}executeCommand({templateID:e,executionID:t,command:n}){var s,i,o;null===(s=this.logger)||void 0===s||s.log("Exec shell code cell",{templateID:e,executionID:t,command:n});const r=this.envs.find((t=>t.templateID===e));r?r.isReady?function(e,{environmentID:t,executionID:n,command:s}){const i={type:l.RunningEnvironment.ExecCmd,payload:{environmentID:t,executionID:n,command:s}};e.send(i)}(this.opts.conn,{environmentID:r.id,executionID:t,command:n}):null===(o=this.logger)||void 0===o||o.error("Environment is not ready",{templateID:e,executionID:t,command:n}):null===(i=this.logger)||void 0===i||i.error("Environment not found",{templateID:e,executionID:t,command:n})}}class C{constructor(){this.logger=new n("Runner"),this.conn=new c,this.sessManager=new g(this.conn)}static get obj(){return C._obj||(C._obj=new C)}get session(){return this.sessManager.session}get status(){return this.sessManager.status}reset(){this.logger.log("Reset"),this.sessManager.reset()}createContext(e){return new D(Object.assign(Object.assign({},e),{conn:this.conn}))}__debug__loadNewSession(){this.logger.log("__debug__loadNewSession"),this.sessManager.reset()}}const S=(E="1234567890abcdefghijklmnopqrstuvwxyz",y=6,()=>{let e="",t=y;for(;t--;)e+=E[Math.random()*E.length|0];return e});var E,y,R;exports.DevbookStatus=void 0,(R=exports.DevbookStatus||(exports.DevbookStatus={}))[R.Disconnected=0]="Disconnected",R[R.Connecting=1]="Connecting",R[R.Connected=2]="Connected";class I{constructor(e){this.opts=e,this._isDestroyed=!1,this._isEnvReady=!1,this._sessionStatus=h.Disconnected,this._status=exports.DevbookStatus.Disconnected;const t="default";this.contextID=t;const n=S();this.executionID=n;const s=e=>this.isEnvReady=e,i=e=>this.sessionStatus=e;this.context=C.obj.createContext({debug:e.debug,contextID:t,onEnvChange(e){s(e.isReady)},onSessionChange({status:e}){i(e)},onCmdOut(t){var s,i;t.executionID===n&&(void 0!==t.stdout&&(null===(s=e.onStdout)||void 0===s||s.call(e,t.stdout)),void 0!==t.stderr&&(null===(i=e.onStderr)||void 0===i||i.call(e,t.stderr)))}}),this.context.createRunningEnvironment({templateID:e.env})}get isDestroyed(){return this._isDestroyed}set isDestroyed(e){this._isDestroyed=e,this.updateStatus()}get isEnvReady(){return this._isEnvReady}set isEnvReady(e){this._isEnvReady=e,this.updateStatus()}get sessionStatus(){return this._sessionStatus}set sessionStatus(e){this._sessionStatus=e,this.updateStatus()}get status(){return this._status}set status(e){var t,n;this._status=e,null===(n=(t=this.opts).onStatusChange)||void 0===n||n.call(t,e)}runCmd(e){this.status!==exports.DevbookStatus.Disconnected&&this.context.executeCommand({templateID:this.opts.env,executionID:this.executionID,command:e})}runCode(e){const n=t[this.opts.env].toCommand(e);this.runCmd(n)}destroy(){this.context.destroy(),this.isDestroyed=!0}updateStatus(){if(this.isDestroyed)return void(this.status!==exports.DevbookStatus.Disconnected&&(this.status=exports.DevbookStatus.Disconnected));let e;switch(this.sessionStatus){case h.Disconnected:e=exports.DevbookStatus.Disconnected;break;case h.Connecting:e=exports.DevbookStatus.Connecting;break;case h.Connected:if(!this.isEnvReady){e=exports.DevbookStatus.Connecting;break}e=exports.DevbookStatus.Connected}this.status=e}}exports.Devbook=I,exports.useDevbook=function({env:t,debug:n}){const[s,i]=e.useState(),[o,r]=e.useState(exports.DevbookStatus.Disconnected),[a,l]=e.useState([]),[c,d]=e.useState([]),h=e.useCallback((e=>{s&&(d([]),l([]),s.runCmd(e))}),[s]),u=e.useCallback((e=>{s&&(d([]),l([]),s.runCode(e))}),[s]);return e.useEffect((function(){const e=new I({debug:n,env:t,onStatusChange(e){r(e)},onStderr(e){l((t=>[...t,e]))},onStdout(e){d((t=>[...t,e]))}});return d([]),l([]),i(e),()=>{e.destroy()}}),[t,n]),{stderr:a,stdout:c,runCmd:h,runCode:u,status:o}}; | ||
//# sourceMappingURL=index.js.map |
@@ -30,2 +30,5 @@ import { Env } from './constants'; | ||
private readonly contextID; | ||
private _isDestroyed; | ||
private get isDestroyed(); | ||
private set isDestroyed(value); | ||
private _isEnvReady; | ||
@@ -39,4 +42,4 @@ private get isEnvReady(); | ||
/** | ||
* Current status of this `Devbook`'s connection. | ||
*/ | ||
* Current status of this `Devbook`'s connection. | ||
*/ | ||
get status(): DevbookStatus; | ||
@@ -86,4 +89,8 @@ private set status(value); | ||
runCode(code: string): void; | ||
/** | ||
* Disconnect this Devbook from the VM. | ||
*/ | ||
destroy(): void; | ||
private updateStatus; | ||
} | ||
export default Devbook; |
@@ -1,2 +0,2 @@ | ||
import{useState as n,useCallback as e,useEffect as t}from"react";var s;!function(n){n.NodeJS="nodejs-v16"}(s||(s={}));const i={"nodejs-v16":{id:"nodejs-v16",image:"us-central1-docker.pkg.dev/devbookhq/devbook-runner-templates/nodejs-v16:latest",root_dir:"/home/runner",code_cells_dir:"/home/runner/src",toCommand:n=>`node -e "${n}"`}};class o{constructor(n,e=!1){this.logID=n,this.isEnabled=e}id(){return"function"==typeof this.logID?this.logID():this.logID}log(...n){this.isEnabled&&console.log(`[36m[${this.id()}][0m`,...n)}warn(...n){this.isEnabled&&console.warn(`[36m[${this.id()}][0m`,...n)}error(...n){console.error(`[31m[${this.id()} ERROR][0m`,...n)}} | ||
import{useState as e,useCallback as n,useEffect as t}from"react";var s;!function(e){e.NodeJS="nodejs-v16"}(s||(s={}));const i={"nodejs-v16":{id:"nodejs-v16",image:"us-central1-docker.pkg.dev/devbookhq/devbook-runner-templates/nodejs-v16:latest",root_dir:"/home/runner",code_cells_dir:"/home/runner/src",toCommand:e=>`node -e "${e}"`}};class o{constructor(e,n=!1){this.logID=e,this.isEnabled=n}id(){return"function"==typeof this.logID?this.logID():this.logID}log(...e){this.isEnabled&&console.log(`[36m[${this.id()}][0m`,...e)}warn(...e){this.isEnabled&&console.warn(`[36m[${this.id()}][0m`,...e)}error(...e){console.error(`[31m[${this.id()} ERROR][0m`,...e)}} | ||
/*! ***************************************************************************** | ||
@@ -15,3 +15,3 @@ Copyright (c) Microsoft Corporation. | ||
PERFORMANCE OF THIS SOFTWARE. | ||
***************************************************************************** */function r(n,e,t,s){return new(t||(t=Promise))((function(i,o){function r(n){try{a(s.next(n))}catch(n){o(n)}}function l(n){try{a(s.throw(n))}catch(n){o(n)}}function a(n){var e;n.done?i(n.value):(e=n.value,e instanceof t?e:new t((function(n){n(e)}))).then(r,l)}a((s=s.apply(n,e||[])).next())}))}function l(n){return new Promise((e=>setTimeout(e,n)))}var a,c,d;!function(n){n.Error="Runner.Error"}(a||(a={})),function(n){n.Start="RunningEnvironment.Start",n.StartAck="RunningEnvironment.StartAck",n.Eval="RunningEnvironment.Eval",n.FSEventCreate="RunningEnvironment.FSEventCreate",n.FSEventRemove="RunningEnvironment.FSEventRemove",n.FSEventWrite="RunningEnvironment.FSEventWrite",n.CreateDir="RunningEnvironment.CreateDir",n.ListDir="RunningEnvironment.ListDir",n.WriteFile="RunningEnvironment.WriteFile",n.GetFile="RunningEnvironment.GetFile",n.RemoveFile="RunningEnvironment.RemoveFile",n.DirContent="RunningEnvironment.DirContent",n.FileContent="RunningEnvironment.FileContent",n.Stdout="RunningEnvironment.Stdout",n.Stderr="RunningEnvironment.Stderr",n.ExecCmd="RunningEnvironment.ExecCmd",n.KillCmd="RunningEnvironment.KillCmd",n.ListRunningCmds="RunningEnvironment.ListRunningCmds",n.CmdOut="RunningEnvironment.CmdOut",n.CmdExit="RunningEnvironment.CmdExit",n.RunningCmds="RunningEnvironment.RunningCmds"}(c||(c={})),function(n){n.Error="CodeCell.Error"}(d||(d={}));const h={Runner:a,RunningEnvironment:c,CodeCell:d};class g{constructor(){this.url="wss://orchestrator.usedevbook.com",this.logger=new o("WebSocketConnection"),this.handlers=[]}get state(){var n;return null===(n=this.client)||void 0===n?void 0:n.readyState}get isClosed(){if(void 0!==this.client)return this.client.readyState===this.client.CLOSED}get isClosing(){if(void 0!==this.client)return this.client.readyState===this.client.CLOSING}get isOpen(){if(void 0!==this.client)return this.client.readyState===this.client.OPEN}get isConnecting(){if(void 0!==this.client)return this.client.readyState===this.client.CONNECTING}subscribeHandler(n){return this.handlers.push(n),()=>{this.handlers=this.handlers.filter((e=>e!==n))}}connect(n){(!this.client||this.client.readyState!==this.client.CONNECTING&&this.client.readyState!==this.client.OPEN)&&(n||this.sessionID?(n?(this.logger.log(`Will try to connect to session "${n}"`),this.sessionID=n):!n&&this.sessionID&&this.logger.log(`Will try to connect to previous session "${this.sessionID}"`),this.client=new WebSocket(`${this.url}/session/ws/${this.sessionID}`),this.client.onopen=()=>this.handleOpen(),this.client.onmessage=n=>{this.logger.log("Received (raw)",{msg:n}),this.handleMessage(n)},this.client.onerror=n=>this.handleError(n),this.client.onclose=n=>this.handleClose(n)):this.logger.error("Cannot connect, no session ID passed to the function and no session ID saved from the previous session"))}send(n){this.client&&this.client.readyState===this.client.OPEN?(this.logger.log("Send",n),this._send(n)):this.logger.warn("Trying to send a message while not being in the `OPEN` state or without established connection, message will be discarded",n)}close(){var n;this.logger.log("Closing connection"),null===(n=this.client)||void 0===n||n.close(1e3)}handleOpen(){var n;this.logger.log("Connection opened",{readyState:null===(n=this.client)||void 0===n?void 0:n.readyState}),this.handlers.forEach((n=>n.onOpen()))}_send(n){var e,t;null===(e=this.client)||void 0===e||e.send((t=n,JSON.stringify(t,(()=>{const n=new WeakSet;return(e,t)=>{if("object"==typeof t&&null!==t){if(n.has(t))return;n.add(t)}return t}})(),2)))}handleClose(n){return r(this,void 0,void 0,(function*(){this.logger.log("Connection closed",n),this.handlers.forEach((n=>n.onClose())),this.logger.log("Will try to reconnect in 3s"),yield l(3e3),this.connect()}))}handleError(n){var e;this.logger.error("Connection error",n),null===(e=this.client)||void 0===e||e.close()}handleMessage(n){if(!n.data)return void this.logger.error("Message has empty data field",n);const e=JSON.parse(n.data);if(!e.type)return void this.logger.error("Message has no type",e);const t=e;Object.values(h.RunningEnvironment).includes(t.type)||Object.values(h.Runner).includes(t.type)||Object.values(h.CodeCell).includes(t.type)?t.type!==h.Runner.Error?(this.logger.log("Received (parsed)",t),this.handlers.forEach((n=>n.onMessage(t)))):this.logger.error("Runner error",t):this.logger.error('Message "type" field has unexpected value',t)}}var u,v;!function(n){n.Ok="Ok",n.Terminated="Terminated"}(u||(u={}));class m{constructor(n,e=new Date){this.id=n,this.lastPing=e,this.logger=new o("RunnerSession"),this.url="https://orchestrator.usedevbook.com"}ping(){return r(this,void 0,void 0,(function*(){this.logger.log(`Pinging session "${this.id}"`);const n=JSON.stringify({sessionID:this.id});try{const e=yield fetch(`${this.url}/session/ping`,{method:"POST",headers:{"Content-Type":"application/json"},body:n}),t=yield e.json();if(!e.ok)throw this.logger.error(e.headers,t),new Error("Non-OK response when trying to ping active Runner session");if(t.status===u.Terminated)throw new Error(`[keepAlive]: Session '${this.id}' is terminated`);this.lastPing=new Date}catch(n){throw this.logger.error(n),new Error("Failed to ping active Runner session")}}))}}!function(n){n.Connected="Connected",n.Connecting="Connecting",n.Disconnected="Disconnected"}(v||(v={}));class C{constructor(n){this.conn=n,this.logger=new o("SessionManager"),this.url="https://orchestrator.usedevbook.com",this.isGettingSessionActive=!1,this.status=v.Disconnected,this.logger.log("Initialize"),this.getSession()}get cachedSessionID(){return sessionStorage.getItem("dbk_sdk_session_id")}set cachedSessionID(n){null===n?(this.logger.log("Cleared last sessionID"),sessionStorage.removeItem("dbk_sdk_session_id")):(this.logger.log(`Saved sessionID "${n}" as last sessionID`),sessionStorage.setItem("dbk_sdk_session_id",n))}reset(){this.logger.log("Reset"),this.status=v.Disconnected,this.cachedSessionID=null,this.conn.close(),this.session=void 0}getSession(){var n;return r(this,void 0,void 0,(function*(){if(!this.isGettingSessionActive)for(this.isGettingSessionActive=!0;;){this.status=v.Connecting;try{const e=this.cachedSessionID?`${this.url}/session/${this.cachedSessionID}`:`${this.url}/session`;this.cachedSessionID?this.logger.log(`Restoring old Runner session "${this.cachedSessionID}"`):this.logger.log("Acquiring new Runner session");const t=yield fetch(e),s=yield t.json();if(!t.ok){this.logger.error("Non-OK response when trying to ping active Runner session. Will try again in 3s",t.headers,s),yield l(3e3);continue}for(this.session=new m(s.sessionID),this.logger.log(`Acquired session "${this.session.id}"`),this.cachedSessionID=this.session.id,this.status=v.Connected,this.conn.connect(this.session.id),this.logger.log(`Started pinging session "${this.session.id}"`);this.session;)try{yield this.session.ping(),yield l(5e3)}catch(n){this.logger.error(`Failed to ping session "${this.session.id}"`,n);break}this.logger.log(`Stopped pinging session "${null===(n=this.session)||void 0===n?void 0:n.id}"`),this.session=void 0,this.status=v.Disconnected,this.conn.close()}catch(n){this.logger.error("Failed to acquire Runner session. Will try again in 3s",n),yield l(3e3)}}}))}}function p(n){return function(n){const e=Array.from(n).reduce(((n,e)=>0|31*n+e.charCodeAt(0)),0);return("0000000"+(e>>>0).toString(16)).slice(-8)}(n)}class D{constructor(n,e){this.contextID=n,this.templateID=e,this.isReady=!1,this.id=`${n}_${p(e)}`,this.template=i[this.templateID]}}function E(n,{environmentID:e,template:t}){const s={type:h.RunningEnvironment.Start,payload:{environmentID:e,template:t}};n.send(s)}class S{constructor(n){this.opts=n,this.envs=[],this.logger=new o("EvaluationContext",n.debug),this.unsubscribeConnHandler=this.opts.conn.subscribeHandler({onOpen:this.handleConnectionOpen.bind(this),onMessage:this.handleConnectionMessage.bind(this),onClose:this.handleConnectionClose.bind(this)}),this.opts.conn.isOpen&&this.handleConnectionOpen(),this.opts.conn.isClosed&&this.handleConnectionClose()}get contextID(){return this.opts.contextID}handleConnectionOpen(){var n,e;this.restart(),null===(e=(n=this.opts).onSessionChange)||void 0===e||e.call(n,{status:v.Connected})}handleConnectionClose(){var n,e;null===(e=(n=this.opts).onSessionChange)||void 0===e||e.call(n,{status:v.Connecting})}restart(){var n;return null===(n=this.logger)||void 0===n||n.log("Restart - session:",this.opts.conn.sessionID),this.envs.forEach((n=>{n.isReady=!1,E(this.opts.conn,{environmentID:n.id,template:n.template})}))}destroy(){var n;null===(n=this.logger)||void 0===n||n.log("Destroy"),this.envs=[],this.unsubscribeConnHandler()}handleConnectionMessage(n){var e,t;switch(null===(e=this.logger)||void 0===e||e.log("Handling message from remote Runner",{message:n}),n.type){case h.RunningEnvironment.StartAck:{const e=n;this.vmenv_handleStartAck(e.payload);break}case h.RunningEnvironment.CmdOut:{const e=n;this.vmenv_handleCmdOut(e.payload);break}default:null===(t=this.logger)||void 0===t||t.warn("Unknown message type",{message:n})}}deleteRunningEnvironment({templateID:n}){var e;null===(e=this.logger)||void 0===e||e.log('Handling "DeleteEnvironment"',{templateID:n}),this.envs=this.envs.filter((e=>e.templateID!==n))}createRunningEnvironment({templateID:n}){var e,t,s;null===(e=this.logger)||void 0===e||e.log('Handling "CreateEnvironment"',{templateID:n});const i=this.envs.find((e=>e.templateID===n));if(i)return i;const o=new D(this.contextID,n);return this.envs=[...this.envs,o],E(this.opts.conn,{environmentID:o.id,template:o.template}),null===(s=(t=this.opts).onEnvChange)||void 0===s||s.call(t,o),o}vmenv_handleStartAck(n){var e,t,s,i;null===(e=this.logger)||void 0===e||e.log('[vmenv] Handling "StartAck"',{payload:n});const o=this.envs.find((e=>e.id===n.environmentID));o?(o.isReady=!0,null===(i=(s=this.opts).onEnvChange)||void 0===i||i.call(s,o)):null===(t=this.logger)||void 0===t||t.warn("Environment not found",{payload:n})}vmenv_handleCmdOut(n){var e,t,s;null===(e=this.logger)||void 0===e||e.log('[vmenv] Handling "CmdOut"',n),null===(s=(t=this.opts).onCmdOut)||void 0===s||s.call(t,n)}executeCommand({templateID:n,executionID:e,command:t}){var s,i,o;null===(s=this.logger)||void 0===s||s.log("Exec shell code cell",{templateID:n,executionID:e,command:t});const r=this.envs.find((e=>e.templateID===n));r?r.isReady?function(n,{environmentID:e,executionID:t,command:s}){const i={type:h.RunningEnvironment.ExecCmd,payload:{environmentID:e,executionID:t,command:s}};n.send(i)}(this.opts.conn,{environmentID:r.id,executionID:e,command:t}):null===(o=this.logger)||void 0===o||o.error("Environment is not ready",{templateID:n,executionID:e,command:t}):null===(i=this.logger)||void 0===i||i.error("Environment not found",{templateID:n,executionID:e,command:t})}}class y{constructor(){this.logger=new o("Runner"),this.conn=new g,this.sessManager=new C(this.conn)}static get obj(){return y._obj||(y._obj=new y)}get session(){return this.sessManager.session}get status(){return this.sessManager.status}reset(){this.logger.log("Reset"),this.sessManager.reset()}createContext(n){return new S(Object.assign(Object.assign({},n),{conn:this.conn}))}__debug__loadNewSession(){this.logger.log("__debug__loadNewSession"),this.sessManager.reset()}}const R=(I="1234567890abcdefghijklmnopqrstuvwxyz",f=6,()=>{let n="",e=f;for(;e--;)n+=I[Math.random()*I.length|0];return n});var I,f,b;!function(n){n[n.Disconnected=0]="Disconnected",n[n.Connecting=1]="Connecting",n[n.Connected=2]="Connected"}(b||(b={}));class w{constructor(n){this.opts=n,this._isEnvReady=!1,this._sessionStatus=v.Disconnected,this._status=b.Disconnected;const e="default";this.contextID=e;const t=R();this.executionID=t;const s=n=>this.isEnvReady=n,i=n=>this.sessionStatus=n;this.context=y.obj.createContext({debug:n.debug,contextID:e,onEnvChange(n){s(n.isReady)},onSessionChange({status:n}){i(n)},onCmdOut(e){var s,i;e.executionID===t&&(void 0!==e.stdout&&(null===(s=n.onStdout)||void 0===s||s.call(n,e.stdout)),void 0!==e.stderr&&(null===(i=n.onStderr)||void 0===i||i.call(n,e.stderr)))}}),this.context.createRunningEnvironment({templateID:n.env})}get isEnvReady(){return this._isEnvReady}set isEnvReady(n){this._isEnvReady=n,this.updateStatus()}get sessionStatus(){return this._sessionStatus}set sessionStatus(n){this._sessionStatus=n,this.updateStatus()}get status(){return this._status}set status(n){var e,t;this._status=n,null===(t=(e=this.opts).onStatusChange)||void 0===t||t.call(e,n)}runCmd(n){this.context.executeCommand({templateID:this.opts.env,executionID:this.executionID,command:n})}runCode(n){const e=i[this.opts.env].toCommand(n);this.runCmd(e)}updateStatus(){let n;switch(this.sessionStatus){case v.Disconnected:n=b.Disconnected;break;case v.Connecting:n=b.Connecting;break;case v.Connected:if(!this.isEnvReady){n=b.Connecting;break}n=b.Connected}this.status=n}}function O({env:s,debug:i}){const[o,r]=n(),[l,a]=n(b.Disconnected),[c,d]=n([]),[h,g]=n([]),u=e((n=>{o&&(g([]),d([]),o.runCmd(n))}),[o]),v=e((n=>{o&&(g([]),d([]),o.runCode(n))}),[o]);return t((function(){const n=new w({debug:i,env:s,onStatusChange(n){a(n)},onStderr(n){d((e=>[...e,n]))},onStdout(n){g((e=>[...e,n]))}});g([]),d([]),r(n)}),[s,i]),{stderr:c,stdout:h,runCmd:u,runCode:v,status:l}}export{w as Devbook,b as DevbookStatus,s as Env,O as useDevbook}; | ||
***************************************************************************** */function r(e,n,t,s){return new(t||(t=Promise))((function(i,o){function r(e){try{a(s.next(e))}catch(e){o(e)}}function l(e){try{a(s.throw(e))}catch(e){o(e)}}function a(e){var n;e.done?i(e.value):(n=e.value,n instanceof t?n:new t((function(e){e(n)}))).then(r,l)}a((s=s.apply(e,n||[])).next())}))}function l(e){return new Promise((n=>setTimeout(n,e)))}var a,c,d;!function(e){e.Error="Runner.Error"}(a||(a={})),function(e){e.Start="RunningEnvironment.Start",e.StartAck="RunningEnvironment.StartAck",e.Eval="RunningEnvironment.Eval",e.FSEventCreate="RunningEnvironment.FSEventCreate",e.FSEventRemove="RunningEnvironment.FSEventRemove",e.FSEventWrite="RunningEnvironment.FSEventWrite",e.CreateDir="RunningEnvironment.CreateDir",e.ListDir="RunningEnvironment.ListDir",e.WriteFile="RunningEnvironment.WriteFile",e.GetFile="RunningEnvironment.GetFile",e.RemoveFile="RunningEnvironment.RemoveFile",e.DirContent="RunningEnvironment.DirContent",e.FileContent="RunningEnvironment.FileContent",e.Stdout="RunningEnvironment.Stdout",e.Stderr="RunningEnvironment.Stderr",e.ExecCmd="RunningEnvironment.ExecCmd",e.KillCmd="RunningEnvironment.KillCmd",e.ListRunningCmds="RunningEnvironment.ListRunningCmds",e.CmdOut="RunningEnvironment.CmdOut",e.CmdExit="RunningEnvironment.CmdExit",e.RunningCmds="RunningEnvironment.RunningCmds"}(c||(c={})),function(e){e.Error="CodeCell.Error"}(d||(d={}));const h={Runner:a,RunningEnvironment:c,CodeCell:d};class g{constructor(){this.url="wss://orchestrator.usedevbook.com",this.logger=new o("WebSocketConnection"),this.handlers=[]}get state(){var e;return null===(e=this.client)||void 0===e?void 0:e.readyState}get isClosed(){if(void 0!==this.client)return this.client.readyState===this.client.CLOSED}get isClosing(){if(void 0!==this.client)return this.client.readyState===this.client.CLOSING}get isOpen(){if(void 0!==this.client)return this.client.readyState===this.client.OPEN}get isConnecting(){if(void 0!==this.client)return this.client.readyState===this.client.CONNECTING}subscribeHandler(e){return this.handlers.push(e),()=>{this.handlers=this.handlers.filter((n=>n!==e))}}connect(e){(!this.client||this.client.readyState!==this.client.CONNECTING&&this.client.readyState!==this.client.OPEN)&&(e||this.sessionID?(e?(this.logger.log(`Will try to connect to session "${e}"`),this.sessionID=e):!e&&this.sessionID&&this.logger.log(`Will try to connect to previous session "${this.sessionID}"`),this.client=new WebSocket(`${this.url}/session/ws/${this.sessionID}`),this.client.onopen=()=>this.handleOpen(),this.client.onmessage=e=>{this.logger.log("Received (raw)",{msg:e}),this.handleMessage(e)},this.client.onerror=e=>this.handleError(e),this.client.onclose=e=>this.handleClose(e)):this.logger.error("Cannot connect, no session ID passed to the function and no session ID saved from the previous session"))}send(e){this.client&&this.client.readyState===this.client.OPEN?(this.logger.log("Send",e),this._send(e)):this.logger.warn("Trying to send a message while not being in the `OPEN` state or without established connection, message will be discarded",e)}close(){var e;this.logger.log("Closing connection"),null===(e=this.client)||void 0===e||e.close(1e3)}handleOpen(){var e;this.logger.log("Connection opened",{readyState:null===(e=this.client)||void 0===e?void 0:e.readyState}),this.handlers.forEach((e=>e.onOpen()))}_send(e){var n,t;null===(n=this.client)||void 0===n||n.send((t=e,JSON.stringify(t,(()=>{const e=new WeakSet;return(n,t)=>{if("object"==typeof t&&null!==t){if(e.has(t))return;e.add(t)}return t}})(),2)))}handleClose(e){return r(this,void 0,void 0,(function*(){this.logger.log("Connection closed",e),this.handlers.forEach((e=>e.onClose())),this.logger.log("Will try to reconnect in 3s"),yield l(3e3),this.connect()}))}handleError(e){var n;this.logger.error("Connection error",e),null===(n=this.client)||void 0===n||n.close()}handleMessage(e){if(!e.data)return void this.logger.error("Message has empty data field",e);const n=JSON.parse(e.data);if(!n.type)return void this.logger.error("Message has no type",n);const t=n;Object.values(h.RunningEnvironment).includes(t.type)||Object.values(h.Runner).includes(t.type)||Object.values(h.CodeCell).includes(t.type)?t.type!==h.Runner.Error?(this.logger.log("Received (parsed)",t),this.handlers.forEach((e=>e.onMessage(t)))):this.logger.error("Runner error",t):this.logger.error('Message "type" field has unexpected value',t)}}var u,v;!function(e){e.Ok="Ok",e.Terminated="Terminated"}(u||(u={}));class m{constructor(e,n=new Date){this.id=e,this.lastPing=n,this.logger=new o("RunnerSession"),this.url="https://orchestrator.usedevbook.com"}ping(){return r(this,void 0,void 0,(function*(){this.logger.log(`Pinging session "${this.id}"`);const e=JSON.stringify({sessionID:this.id});try{const n=yield fetch(`${this.url}/session/ping`,{method:"POST",headers:{"Content-Type":"application/json"},body:e}),t=yield n.json();if(!n.ok)throw this.logger.error(n.headers,t),new Error("Non-OK response when trying to ping active Runner session");if(t.status===u.Terminated)throw new Error(`[keepAlive]: Session '${this.id}' is terminated`);this.lastPing=new Date}catch(e){throw this.logger.error(e),new Error("Failed to ping active Runner session")}}))}}!function(e){e.Connected="Connected",e.Connecting="Connecting",e.Disconnected="Disconnected"}(v||(v={}));class C{constructor(e){this.conn=e,this.logger=new o("SessionManager"),this.url="https://orchestrator.usedevbook.com",this.isGettingSessionActive=!1,this.status=v.Disconnected,this.logger.log("Initialize"),this.getSession()}get cachedSessionID(){return sessionStorage.getItem("dbk_sdk_session_id")}set cachedSessionID(e){null===e?(this.logger.log("Cleared last sessionID"),sessionStorage.removeItem("dbk_sdk_session_id")):(this.logger.log(`Saved sessionID "${e}" as last sessionID`),sessionStorage.setItem("dbk_sdk_session_id",e))}reset(){this.logger.log("Reset"),this.status=v.Disconnected,this.cachedSessionID=null,this.conn.close(),this.session=void 0}getSession(){var e;return r(this,void 0,void 0,(function*(){if(!this.isGettingSessionActive)for(this.isGettingSessionActive=!0;;){this.status=v.Connecting;try{const n=this.cachedSessionID?`${this.url}/session/${this.cachedSessionID}`:`${this.url}/session`;this.cachedSessionID?this.logger.log(`Restoring old Runner session "${this.cachedSessionID}"`):this.logger.log("Acquiring new Runner session");const t=yield fetch(n),s=yield t.json();if(!t.ok){this.logger.error("Non-OK response when trying to ping active Runner session. Will try again in 3s",t.headers,s),yield l(3e3);continue}for(this.session=new m(s.sessionID),this.logger.log(`Acquired session "${this.session.id}"`),this.cachedSessionID=this.session.id,this.status=v.Connected,this.conn.connect(this.session.id),this.logger.log(`Started pinging session "${this.session.id}"`);this.session;)try{yield this.session.ping(),yield l(5e3)}catch(e){this.logger.error(`Failed to ping session "${this.session.id}"`,e);break}this.logger.log(`Stopped pinging session "${null===(e=this.session)||void 0===e?void 0:e.id}"`),this.session=void 0,this.status=v.Disconnected,this.conn.close()}catch(e){this.logger.error("Failed to acquire Runner session. Will try again in 3s",e),yield l(3e3)}}}))}}function p(e){return function(e){const n=Array.from(e).reduce(((e,n)=>0|31*e+n.charCodeAt(0)),0);return("0000000"+(n>>>0).toString(16)).slice(-8)}(e)}class D{constructor(e,n){this.contextID=e,this.templateID=n,this.isReady=!1,this.id=`${e}_${p(n)}`,this.template=i[this.templateID]}}function E(e,{environmentID:n,template:t}){const s={type:h.RunningEnvironment.Start,payload:{environmentID:n,template:t}};e.send(s)}class S{constructor(e){this.opts=e,this.envs=[],this.logger=new o("EvaluationContext",e.debug),this.unsubscribeConnHandler=this.opts.conn.subscribeHandler({onOpen:this.handleConnectionOpen.bind(this),onMessage:this.handleConnectionMessage.bind(this),onClose:this.handleConnectionClose.bind(this)}),this.opts.conn.isOpen&&this.handleConnectionOpen(),this.opts.conn.isClosed&&this.handleConnectionClose()}get contextID(){return this.opts.contextID}handleConnectionOpen(){var e,n;this.restart(),null===(n=(e=this.opts).onSessionChange)||void 0===n||n.call(e,{status:v.Connected})}handleConnectionClose(){var e,n;null===(n=(e=this.opts).onSessionChange)||void 0===n||n.call(e,{status:v.Connecting})}restart(){var e;return null===(e=this.logger)||void 0===e||e.log("Restart - session:",this.opts.conn.sessionID),this.envs.forEach((e=>{e.isReady=!1,E(this.opts.conn,{environmentID:e.id,template:e.template})}))}destroy(){var e;null===(e=this.logger)||void 0===e||e.log("Destroy"),this.envs=[],this.unsubscribeConnHandler()}handleConnectionMessage(e){var n,t;switch(null===(n=this.logger)||void 0===n||n.log("Handling message from remote Runner",{message:e}),e.type){case h.RunningEnvironment.StartAck:{const n=e;this.vmenv_handleStartAck(n.payload);break}case h.RunningEnvironment.CmdOut:{const n=e;this.vmenv_handleCmdOut(n.payload);break}default:null===(t=this.logger)||void 0===t||t.warn("Unknown message type",{message:e})}}deleteRunningEnvironment({templateID:e}){var n;null===(n=this.logger)||void 0===n||n.log('Handling "DeleteEnvironment"',{templateID:e}),this.envs=this.envs.filter((n=>n.templateID!==e))}createRunningEnvironment({templateID:e}){var n,t,s;null===(n=this.logger)||void 0===n||n.log('Handling "CreateEnvironment"',{templateID:e});const i=this.envs.find((n=>n.templateID===e));if(i)return i;const o=new D(this.contextID,e);return this.envs=[...this.envs,o],E(this.opts.conn,{environmentID:o.id,template:o.template}),null===(s=(t=this.opts).onEnvChange)||void 0===s||s.call(t,o),o}vmenv_handleStartAck(e){var n,t,s,i;null===(n=this.logger)||void 0===n||n.log('[vmenv] Handling "StartAck"',{payload:e});const o=this.envs.find((n=>n.id===e.environmentID));o?(o.isReady=!0,null===(i=(s=this.opts).onEnvChange)||void 0===i||i.call(s,o)):null===(t=this.logger)||void 0===t||t.warn("Environment not found",{payload:e})}vmenv_handleCmdOut(e){var n,t,s;null===(n=this.logger)||void 0===n||n.log('[vmenv] Handling "CmdOut"',e),null===(s=(t=this.opts).onCmdOut)||void 0===s||s.call(t,e)}executeCommand({templateID:e,executionID:n,command:t}){var s,i,o;null===(s=this.logger)||void 0===s||s.log("Exec shell code cell",{templateID:e,executionID:n,command:t});const r=this.envs.find((n=>n.templateID===e));r?r.isReady?function(e,{environmentID:n,executionID:t,command:s}){const i={type:h.RunningEnvironment.ExecCmd,payload:{environmentID:n,executionID:t,command:s}};e.send(i)}(this.opts.conn,{environmentID:r.id,executionID:n,command:t}):null===(o=this.logger)||void 0===o||o.error("Environment is not ready",{templateID:e,executionID:n,command:t}):null===(i=this.logger)||void 0===i||i.error("Environment not found",{templateID:e,executionID:n,command:t})}}class y{constructor(){this.logger=new o("Runner"),this.conn=new g,this.sessManager=new C(this.conn)}static get obj(){return y._obj||(y._obj=new y)}get session(){return this.sessManager.session}get status(){return this.sessManager.status}reset(){this.logger.log("Reset"),this.sessManager.reset()}createContext(e){return new S(Object.assign(Object.assign({},e),{conn:this.conn}))}__debug__loadNewSession(){this.logger.log("__debug__loadNewSession"),this.sessManager.reset()}}const R=(I="1234567890abcdefghijklmnopqrstuvwxyz",f=6,()=>{let e="",n=f;for(;n--;)e+=I[Math.random()*I.length|0];return e});var I,f,b;!function(e){e[e.Disconnected=0]="Disconnected",e[e.Connecting=1]="Connecting",e[e.Connected=2]="Connected"}(b||(b={}));class w{constructor(e){this.opts=e,this._isDestroyed=!1,this._isEnvReady=!1,this._sessionStatus=v.Disconnected,this._status=b.Disconnected;const n="default";this.contextID=n;const t=R();this.executionID=t;const s=e=>this.isEnvReady=e,i=e=>this.sessionStatus=e;this.context=y.obj.createContext({debug:e.debug,contextID:n,onEnvChange(e){s(e.isReady)},onSessionChange({status:e}){i(e)},onCmdOut(n){var s,i;n.executionID===t&&(void 0!==n.stdout&&(null===(s=e.onStdout)||void 0===s||s.call(e,n.stdout)),void 0!==n.stderr&&(null===(i=e.onStderr)||void 0===i||i.call(e,n.stderr)))}}),this.context.createRunningEnvironment({templateID:e.env})}get isDestroyed(){return this._isDestroyed}set isDestroyed(e){this._isDestroyed=e,this.updateStatus()}get isEnvReady(){return this._isEnvReady}set isEnvReady(e){this._isEnvReady=e,this.updateStatus()}get sessionStatus(){return this._sessionStatus}set sessionStatus(e){this._sessionStatus=e,this.updateStatus()}get status(){return this._status}set status(e){var n,t;this._status=e,null===(t=(n=this.opts).onStatusChange)||void 0===t||t.call(n,e)}runCmd(e){this.status!==b.Disconnected&&this.context.executeCommand({templateID:this.opts.env,executionID:this.executionID,command:e})}runCode(e){const n=i[this.opts.env].toCommand(e);this.runCmd(n)}destroy(){this.context.destroy(),this.isDestroyed=!0}updateStatus(){if(this.isDestroyed)return void(this.status!==b.Disconnected&&(this.status=b.Disconnected));let e;switch(this.sessionStatus){case v.Disconnected:e=b.Disconnected;break;case v.Connecting:e=b.Connecting;break;case v.Connected:if(!this.isEnvReady){e=b.Connecting;break}e=b.Connected}this.status=e}}function _({env:s,debug:i}){const[o,r]=e(),[l,a]=e(b.Disconnected),[c,d]=e([]),[h,g]=e([]),u=n((e=>{o&&(g([]),d([]),o.runCmd(e))}),[o]),v=n((e=>{o&&(g([]),d([]),o.runCode(e))}),[o]);return t((function(){const e=new w({debug:i,env:s,onStatusChange(e){a(e)},onStderr(e){d((n=>[...n,e]))},onStdout(e){g((n=>[...n,e]))}});return g([]),d([]),r(e),()=>{e.destroy()}}),[s,i]),{stderr:c,stdout:h,runCmd:u,runCode:v,status:l}}export{w as Devbook,b as DevbookStatus,s as Env,_ as useDevbook}; | ||
//# sourceMappingURL=index.js.map |
@@ -30,2 +30,5 @@ import { Env } from './constants'; | ||
private readonly contextID; | ||
private _isDestroyed; | ||
private get isDestroyed(); | ||
private set isDestroyed(value); | ||
private _isEnvReady; | ||
@@ -39,4 +42,4 @@ private get isEnvReady(); | ||
/** | ||
* Current status of this `Devbook`'s connection. | ||
*/ | ||
* Current status of this `Devbook`'s connection. | ||
*/ | ||
get status(): DevbookStatus; | ||
@@ -86,4 +89,8 @@ private set status(value); | ||
runCode(code: string): void; | ||
/** | ||
* Disconnect this Devbook from the VM. | ||
*/ | ||
destroy(): void; | ||
private updateStatus; | ||
} | ||
export default Devbook; |
@@ -15,3 +15,3 @@ !function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self)["@devbookhq/sdk"]={},e.react)}(this,(function(e,n){"use strict";const t="orchestrator.usedevbook.com",s="dbk_sdk_session_id",i=3e3;e.Env=void 0,(e.Env||(e.Env={})).NodeJS="nodejs-v16";const o={"nodejs-v16":{id:"nodejs-v16",image:"us-central1-docker.pkg.dev/devbookhq/devbook-runner-templates/nodejs-v16:latest",root_dir:"/home/runner",code_cells_dir:"/home/runner/src",toCommand:e=>`node -e "${e}"`}};class r{constructor(e,n=!1){this.logID=e,this.isEnabled=n}id(){return"function"==typeof this.logID?this.logID():this.logID}log(...e){this.isEnabled&&console.log(`[36m[${this.id()}][0m`,...e)}warn(...e){this.isEnabled&&console.warn(`[36m[${this.id()}][0m`,...e)}error(...e){console.error(`[31m[${this.id()} ERROR][0m`,...e)}} | ||
PERFORMANCE OF THIS SOFTWARE. | ||
***************************************************************************** */function l(e,n,t,s){return new(t||(t=Promise))((function(i,o){function r(e){try{a(s.next(e))}catch(e){o(e)}}function l(e){try{a(s.throw(e))}catch(e){o(e)}}function a(e){var n;e.done?i(e.value):(n=e.value,n instanceof t?n:new t((function(e){e(n)}))).then(r,l)}a((s=s.apply(e,n||[])).next())}))}function a(e){return new Promise((n=>setTimeout(n,e)))}var c,d,h;!function(e){e.Error="Runner.Error"}(c||(c={})),function(e){e.Start="RunningEnvironment.Start",e.StartAck="RunningEnvironment.StartAck",e.Eval="RunningEnvironment.Eval",e.FSEventCreate="RunningEnvironment.FSEventCreate",e.FSEventRemove="RunningEnvironment.FSEventRemove",e.FSEventWrite="RunningEnvironment.FSEventWrite",e.CreateDir="RunningEnvironment.CreateDir",e.ListDir="RunningEnvironment.ListDir",e.WriteFile="RunningEnvironment.WriteFile",e.GetFile="RunningEnvironment.GetFile",e.RemoveFile="RunningEnvironment.RemoveFile",e.DirContent="RunningEnvironment.DirContent",e.FileContent="RunningEnvironment.FileContent",e.Stdout="RunningEnvironment.Stdout",e.Stderr="RunningEnvironment.Stderr",e.ExecCmd="RunningEnvironment.ExecCmd",e.KillCmd="RunningEnvironment.KillCmd",e.ListRunningCmds="RunningEnvironment.ListRunningCmds",e.CmdOut="RunningEnvironment.CmdOut",e.CmdExit="RunningEnvironment.CmdExit",e.RunningCmds="RunningEnvironment.RunningCmds"}(d||(d={})),function(e){e.Error="CodeCell.Error"}(h||(h={}));const u={Runner:c,RunningEnvironment:d,CodeCell:h};class g{constructor(){this.url=`wss://${t}`,this.logger=new r("WebSocketConnection"),this.handlers=[]}get state(){var e;return null===(e=this.client)||void 0===e?void 0:e.readyState}get isClosed(){if(void 0!==this.client)return this.client.readyState===this.client.CLOSED}get isClosing(){if(void 0!==this.client)return this.client.readyState===this.client.CLOSING}get isOpen(){if(void 0!==this.client)return this.client.readyState===this.client.OPEN}get isConnecting(){if(void 0!==this.client)return this.client.readyState===this.client.CONNECTING}subscribeHandler(e){return this.handlers.push(e),()=>{this.handlers=this.handlers.filter((n=>n!==e))}}connect(e){(!this.client||this.client.readyState!==this.client.CONNECTING&&this.client.readyState!==this.client.OPEN)&&(e||this.sessionID?(e?(this.logger.log(`Will try to connect to session "${e}"`),this.sessionID=e):!e&&this.sessionID&&this.logger.log(`Will try to connect to previous session "${this.sessionID}"`),this.client=new WebSocket(`${this.url}/session/ws/${this.sessionID}`),this.client.onopen=()=>this.handleOpen(),this.client.onmessage=e=>{this.logger.log("Received (raw)",{msg:e}),this.handleMessage(e)},this.client.onerror=e=>this.handleError(e),this.client.onclose=e=>this.handleClose(e)):this.logger.error("Cannot connect, no session ID passed to the function and no session ID saved from the previous session"))}send(e){this.client&&this.client.readyState===this.client.OPEN?(this.logger.log("Send",e),this._send(e)):this.logger.warn("Trying to send a message while not being in the `OPEN` state or without established connection, message will be discarded",e)}close(){var e;this.logger.log("Closing connection"),null===(e=this.client)||void 0===e||e.close(1e3)}handleOpen(){var e;this.logger.log("Connection opened",{readyState:null===(e=this.client)||void 0===e?void 0:e.readyState}),this.handlers.forEach((e=>e.onOpen()))}_send(e){var n,t;null===(n=this.client)||void 0===n||n.send((t=e,JSON.stringify(t,(()=>{const e=new WeakSet;return(n,t)=>{if("object"==typeof t&&null!==t){if(e.has(t))return;e.add(t)}return t}})(),2)))}handleClose(e){return l(this,void 0,void 0,(function*(){this.logger.log("Connection closed",e),this.handlers.forEach((e=>e.onClose())),this.logger.log("Will try to reconnect in 3s"),yield a(3e3),this.connect()}))}handleError(e){var n;this.logger.error("Connection error",e),null===(n=this.client)||void 0===n||n.close()}handleMessage(e){if(!e.data)return void this.logger.error("Message has empty data field",e);const n=JSON.parse(e.data);if(!n.type)return void this.logger.error("Message has no type",n);const t=n;Object.values(u.RunningEnvironment).includes(t.type)||Object.values(u.Runner).includes(t.type)||Object.values(u.CodeCell).includes(t.type)?t.type!==u.Runner.Error?(this.logger.log("Received (parsed)",t),this.handlers.forEach((e=>e.onMessage(t)))):this.logger.error("Runner error",t):this.logger.error('Message "type" field has unexpected value',t)}}var v,m;!function(e){e.Ok="Ok",e.Terminated="Terminated"}(v||(v={}));class p{constructor(e,n=new Date){this.id=e,this.lastPing=n,this.logger=new r("RunnerSession"),this.url=`https://${t}`}ping(){return l(this,void 0,void 0,(function*(){this.logger.log(`Pinging session "${this.id}"`);const e=JSON.stringify({sessionID:this.id});try{const n=yield fetch(`${this.url}/session/ping`,{method:"POST",headers:{"Content-Type":"application/json"},body:e}),t=yield n.json();if(!n.ok)throw this.logger.error(n.headers,t),new Error("Non-OK response when trying to ping active Runner session");if(t.status===v.Terminated)throw new Error(`[keepAlive]: Session '${this.id}' is terminated`);this.lastPing=new Date}catch(e){throw this.logger.error(e),new Error("Failed to ping active Runner session")}}))}}!function(e){e.Connected="Connected",e.Connecting="Connecting",e.Disconnected="Disconnected"}(m||(m={}));class C{constructor(e){this.conn=e,this.logger=new r("SessionManager"),this.url=`https://${t}`,this.isGettingSessionActive=!1,this.status=m.Disconnected,this.logger.log("Initialize"),this.getSession()}get cachedSessionID(){return sessionStorage.getItem(s)}set cachedSessionID(e){null===e?(this.logger.log("Cleared last sessionID"),sessionStorage.removeItem(s)):(this.logger.log(`Saved sessionID "${e}" as last sessionID`),sessionStorage.setItem(s,e))}reset(){this.logger.log("Reset"),this.status=m.Disconnected,this.cachedSessionID=null,this.conn.close(),this.session=void 0}getSession(){var e;return l(this,void 0,void 0,(function*(){if(!this.isGettingSessionActive)for(this.isGettingSessionActive=!0;;){this.status=m.Connecting;try{const n=this.cachedSessionID?`${this.url}/session/${this.cachedSessionID}`:`${this.url}/session`;this.cachedSessionID?this.logger.log(`Restoring old Runner session "${this.cachedSessionID}"`):this.logger.log("Acquiring new Runner session");const t=yield fetch(n),s=yield t.json();if(!t.ok){this.logger.error("Non-OK response when trying to ping active Runner session. Will try again in 3s",t.headers,s),yield a(i);continue}for(this.session=new p(s.sessionID),this.logger.log(`Acquired session "${this.session.id}"`),this.cachedSessionID=this.session.id,this.status=m.Connected,this.conn.connect(this.session.id),this.logger.log(`Started pinging session "${this.session.id}"`);this.session;)try{yield this.session.ping(),yield a(5e3)}catch(e){this.logger.error(`Failed to ping session "${this.session.id}"`,e);break}this.logger.log(`Stopped pinging session "${null===(e=this.session)||void 0===e?void 0:e.id}"`),this.session=void 0,this.status=m.Disconnected,this.conn.close()}catch(e){this.logger.error("Failed to acquire Runner session. Will try again in 3s",e),yield a(i)}}}))}}function D(e){return function(e){const n=Array.from(e).reduce(((e,n)=>0|31*e+n.charCodeAt(0)),0);return("0000000"+(n>>>0).toString(16)).slice(-8)}(e)}class S{constructor(e,n){this.contextID=e,this.templateID=n,this.isReady=!1,this.id=`${e}_${D(n)}`,this.template=o[this.templateID]}}function E(e,{environmentID:n,template:t}){const s={type:u.RunningEnvironment.Start,payload:{environmentID:n,template:t}};e.send(s)}class f{constructor(e){this.opts=e,this.envs=[],this.logger=new r("EvaluationContext",e.debug),this.unsubscribeConnHandler=this.opts.conn.subscribeHandler({onOpen:this.handleConnectionOpen.bind(this),onMessage:this.handleConnectionMessage.bind(this),onClose:this.handleConnectionClose.bind(this)}),this.opts.conn.isOpen&&this.handleConnectionOpen(),this.opts.conn.isClosed&&this.handleConnectionClose()}get contextID(){return this.opts.contextID}handleConnectionOpen(){var e,n;this.restart(),null===(n=(e=this.opts).onSessionChange)||void 0===n||n.call(e,{status:m.Connected})}handleConnectionClose(){var e,n;null===(n=(e=this.opts).onSessionChange)||void 0===n||n.call(e,{status:m.Connecting})}restart(){var e;return null===(e=this.logger)||void 0===e||e.log("Restart - session:",this.opts.conn.sessionID),this.envs.forEach((e=>{e.isReady=!1,E(this.opts.conn,{environmentID:e.id,template:e.template})}))}destroy(){var e;null===(e=this.logger)||void 0===e||e.log("Destroy"),this.envs=[],this.unsubscribeConnHandler()}handleConnectionMessage(e){var n,t;switch(null===(n=this.logger)||void 0===n||n.log("Handling message from remote Runner",{message:e}),e.type){case u.RunningEnvironment.StartAck:{const n=e;this.vmenv_handleStartAck(n.payload);break}case u.RunningEnvironment.CmdOut:{const n=e;this.vmenv_handleCmdOut(n.payload);break}default:null===(t=this.logger)||void 0===t||t.warn("Unknown message type",{message:e})}}deleteRunningEnvironment({templateID:e}){var n;null===(n=this.logger)||void 0===n||n.log('Handling "DeleteEnvironment"',{templateID:e}),this.envs=this.envs.filter((n=>n.templateID!==e))}createRunningEnvironment({templateID:e}){var n,t,s;null===(n=this.logger)||void 0===n||n.log('Handling "CreateEnvironment"',{templateID:e});const i=this.envs.find((n=>n.templateID===e));if(i)return i;const o=new S(this.contextID,e);return this.envs=[...this.envs,o],E(this.opts.conn,{environmentID:o.id,template:o.template}),null===(s=(t=this.opts).onEnvChange)||void 0===s||s.call(t,o),o}vmenv_handleStartAck(e){var n,t,s,i;null===(n=this.logger)||void 0===n||n.log('[vmenv] Handling "StartAck"',{payload:e});const o=this.envs.find((n=>n.id===e.environmentID));o?(o.isReady=!0,null===(i=(s=this.opts).onEnvChange)||void 0===i||i.call(s,o)):null===(t=this.logger)||void 0===t||t.warn("Environment not found",{payload:e})}vmenv_handleCmdOut(e){var n,t,s;null===(n=this.logger)||void 0===n||n.log('[vmenv] Handling "CmdOut"',e),null===(s=(t=this.opts).onCmdOut)||void 0===s||s.call(t,e)}executeCommand({templateID:e,executionID:n,command:t}){var s,i,o;null===(s=this.logger)||void 0===s||s.log("Exec shell code cell",{templateID:e,executionID:n,command:t});const r=this.envs.find((n=>n.templateID===e));r?r.isReady?function(e,{environmentID:n,executionID:t,command:s}){const i={type:u.RunningEnvironment.ExecCmd,payload:{environmentID:n,executionID:t,command:s}};e.send(i)}(this.opts.conn,{environmentID:r.id,executionID:n,command:t}):null===(o=this.logger)||void 0===o||o.error("Environment is not ready",{templateID:e,executionID:n,command:t}):null===(i=this.logger)||void 0===i||i.error("Environment not found",{templateID:e,executionID:n,command:t})}}class y{constructor(){this.logger=new r("Runner"),this.conn=new g,this.sessManager=new C(this.conn)}static get obj(){return y._obj||(y._obj=new y)}get session(){return this.sessManager.session}get status(){return this.sessManager.status}reset(){this.logger.log("Reset"),this.sessManager.reset()}createContext(e){return new f(Object.assign(Object.assign({},e),{conn:this.conn}))}__debug__loadNewSession(){this.logger.log("__debug__loadNewSession"),this.sessManager.reset()}}const R=(I="1234567890abcdefghijklmnopqrstuvwxyz",b=6,()=>{let e="",n=b;for(;n--;)e+=I[Math.random()*I.length|0];return e});var I,b,w;e.DevbookStatus=void 0,(w=e.DevbookStatus||(e.DevbookStatus={}))[w.Disconnected=0]="Disconnected",w[w.Connecting=1]="Connecting",w[w.Connected=2]="Connected";class k{constructor(n){this.opts=n,this._isEnvReady=!1,this._sessionStatus=m.Disconnected,this._status=e.DevbookStatus.Disconnected;const t="default";this.contextID=t;const s=R();this.executionID=s;const i=e=>this.isEnvReady=e,o=e=>this.sessionStatus=e;this.context=y.obj.createContext({debug:n.debug,contextID:t,onEnvChange(e){i(e.isReady)},onSessionChange({status:e}){o(e)},onCmdOut(e){var t,i;e.executionID===s&&(void 0!==e.stdout&&(null===(t=n.onStdout)||void 0===t||t.call(n,e.stdout)),void 0!==e.stderr&&(null===(i=n.onStderr)||void 0===i||i.call(n,e.stderr)))}}),this.context.createRunningEnvironment({templateID:n.env})}get isEnvReady(){return this._isEnvReady}set isEnvReady(e){this._isEnvReady=e,this.updateStatus()}get sessionStatus(){return this._sessionStatus}set sessionStatus(e){this._sessionStatus=e,this.updateStatus()}get status(){return this._status}set status(e){var n,t;this._status=e,null===(t=(n=this.opts).onStatusChange)||void 0===t||t.call(n,e)}runCmd(e){this.context.executeCommand({templateID:this.opts.env,executionID:this.executionID,command:e})}runCode(e){const n=o[this.opts.env].toCommand(e);this.runCmd(n)}updateStatus(){let n;switch(this.sessionStatus){case m.Disconnected:n=e.DevbookStatus.Disconnected;break;case m.Connecting:n=e.DevbookStatus.Connecting;break;case m.Connected:if(!this.isEnvReady){n=e.DevbookStatus.Connecting;break}n=e.DevbookStatus.Connected}this.status=n}}e.Devbook=k,e.useDevbook=function({env:t,debug:s}){const[i,o]=n.useState(),[r,l]=n.useState(e.DevbookStatus.Disconnected),[a,c]=n.useState([]),[d,h]=n.useState([]),u=n.useCallback((e=>{i&&(h([]),c([]),i.runCmd(e))}),[i]),g=n.useCallback((e=>{i&&(h([]),c([]),i.runCode(e))}),[i]);return n.useEffect((function(){const e=new k({debug:s,env:t,onStatusChange(e){l(e)},onStderr(e){c((n=>[...n,e]))},onStdout(e){h((n=>[...n,e]))}});h([]),c([]),o(e)}),[t,s]),{stderr:a,stdout:d,runCmd:u,runCode:g,status:r}},Object.defineProperty(e,"__esModule",{value:!0})})); | ||
***************************************************************************** */function a(e,n,t,s){return new(t||(t=Promise))((function(i,o){function r(e){try{l(s.next(e))}catch(e){o(e)}}function a(e){try{l(s.throw(e))}catch(e){o(e)}}function l(e){var n;e.done?i(e.value):(n=e.value,n instanceof t?n:new t((function(e){e(n)}))).then(r,a)}l((s=s.apply(e,n||[])).next())}))}function l(e){return new Promise((n=>setTimeout(n,e)))}var c,d,h;!function(e){e.Error="Runner.Error"}(c||(c={})),function(e){e.Start="RunningEnvironment.Start",e.StartAck="RunningEnvironment.StartAck",e.Eval="RunningEnvironment.Eval",e.FSEventCreate="RunningEnvironment.FSEventCreate",e.FSEventRemove="RunningEnvironment.FSEventRemove",e.FSEventWrite="RunningEnvironment.FSEventWrite",e.CreateDir="RunningEnvironment.CreateDir",e.ListDir="RunningEnvironment.ListDir",e.WriteFile="RunningEnvironment.WriteFile",e.GetFile="RunningEnvironment.GetFile",e.RemoveFile="RunningEnvironment.RemoveFile",e.DirContent="RunningEnvironment.DirContent",e.FileContent="RunningEnvironment.FileContent",e.Stdout="RunningEnvironment.Stdout",e.Stderr="RunningEnvironment.Stderr",e.ExecCmd="RunningEnvironment.ExecCmd",e.KillCmd="RunningEnvironment.KillCmd",e.ListRunningCmds="RunningEnvironment.ListRunningCmds",e.CmdOut="RunningEnvironment.CmdOut",e.CmdExit="RunningEnvironment.CmdExit",e.RunningCmds="RunningEnvironment.RunningCmds"}(d||(d={})),function(e){e.Error="CodeCell.Error"}(h||(h={}));const u={Runner:c,RunningEnvironment:d,CodeCell:h};class g{constructor(){this.url=`wss://${t}`,this.logger=new r("WebSocketConnection"),this.handlers=[]}get state(){var e;return null===(e=this.client)||void 0===e?void 0:e.readyState}get isClosed(){if(void 0!==this.client)return this.client.readyState===this.client.CLOSED}get isClosing(){if(void 0!==this.client)return this.client.readyState===this.client.CLOSING}get isOpen(){if(void 0!==this.client)return this.client.readyState===this.client.OPEN}get isConnecting(){if(void 0!==this.client)return this.client.readyState===this.client.CONNECTING}subscribeHandler(e){return this.handlers.push(e),()=>{this.handlers=this.handlers.filter((n=>n!==e))}}connect(e){(!this.client||this.client.readyState!==this.client.CONNECTING&&this.client.readyState!==this.client.OPEN)&&(e||this.sessionID?(e?(this.logger.log(`Will try to connect to session "${e}"`),this.sessionID=e):!e&&this.sessionID&&this.logger.log(`Will try to connect to previous session "${this.sessionID}"`),this.client=new WebSocket(`${this.url}/session/ws/${this.sessionID}`),this.client.onopen=()=>this.handleOpen(),this.client.onmessage=e=>{this.logger.log("Received (raw)",{msg:e}),this.handleMessage(e)},this.client.onerror=e=>this.handleError(e),this.client.onclose=e=>this.handleClose(e)):this.logger.error("Cannot connect, no session ID passed to the function and no session ID saved from the previous session"))}send(e){this.client&&this.client.readyState===this.client.OPEN?(this.logger.log("Send",e),this._send(e)):this.logger.warn("Trying to send a message while not being in the `OPEN` state or without established connection, message will be discarded",e)}close(){var e;this.logger.log("Closing connection"),null===(e=this.client)||void 0===e||e.close(1e3)}handleOpen(){var e;this.logger.log("Connection opened",{readyState:null===(e=this.client)||void 0===e?void 0:e.readyState}),this.handlers.forEach((e=>e.onOpen()))}_send(e){var n,t;null===(n=this.client)||void 0===n||n.send((t=e,JSON.stringify(t,(()=>{const e=new WeakSet;return(n,t)=>{if("object"==typeof t&&null!==t){if(e.has(t))return;e.add(t)}return t}})(),2)))}handleClose(e){return a(this,void 0,void 0,(function*(){this.logger.log("Connection closed",e),this.handlers.forEach((e=>e.onClose())),this.logger.log("Will try to reconnect in 3s"),yield l(3e3),this.connect()}))}handleError(e){var n;this.logger.error("Connection error",e),null===(n=this.client)||void 0===n||n.close()}handleMessage(e){if(!e.data)return void this.logger.error("Message has empty data field",e);const n=JSON.parse(e.data);if(!n.type)return void this.logger.error("Message has no type",n);const t=n;Object.values(u.RunningEnvironment).includes(t.type)||Object.values(u.Runner).includes(t.type)||Object.values(u.CodeCell).includes(t.type)?t.type!==u.Runner.Error?(this.logger.log("Received (parsed)",t),this.handlers.forEach((e=>e.onMessage(t)))):this.logger.error("Runner error",t):this.logger.error('Message "type" field has unexpected value',t)}}var v,m;!function(e){e.Ok="Ok",e.Terminated="Terminated"}(v||(v={}));class p{constructor(e,n=new Date){this.id=e,this.lastPing=n,this.logger=new r("RunnerSession"),this.url=`https://${t}`}ping(){return a(this,void 0,void 0,(function*(){this.logger.log(`Pinging session "${this.id}"`);const e=JSON.stringify({sessionID:this.id});try{const n=yield fetch(`${this.url}/session/ping`,{method:"POST",headers:{"Content-Type":"application/json"},body:e}),t=yield n.json();if(!n.ok)throw this.logger.error(n.headers,t),new Error("Non-OK response when trying to ping active Runner session");if(t.status===v.Terminated)throw new Error(`[keepAlive]: Session '${this.id}' is terminated`);this.lastPing=new Date}catch(e){throw this.logger.error(e),new Error("Failed to ping active Runner session")}}))}}!function(e){e.Connected="Connected",e.Connecting="Connecting",e.Disconnected="Disconnected"}(m||(m={}));class D{constructor(e){this.conn=e,this.logger=new r("SessionManager"),this.url=`https://${t}`,this.isGettingSessionActive=!1,this.status=m.Disconnected,this.logger.log("Initialize"),this.getSession()}get cachedSessionID(){return sessionStorage.getItem(s)}set cachedSessionID(e){null===e?(this.logger.log("Cleared last sessionID"),sessionStorage.removeItem(s)):(this.logger.log(`Saved sessionID "${e}" as last sessionID`),sessionStorage.setItem(s,e))}reset(){this.logger.log("Reset"),this.status=m.Disconnected,this.cachedSessionID=null,this.conn.close(),this.session=void 0}getSession(){var e;return a(this,void 0,void 0,(function*(){if(!this.isGettingSessionActive)for(this.isGettingSessionActive=!0;;){this.status=m.Connecting;try{const n=this.cachedSessionID?`${this.url}/session/${this.cachedSessionID}`:`${this.url}/session`;this.cachedSessionID?this.logger.log(`Restoring old Runner session "${this.cachedSessionID}"`):this.logger.log("Acquiring new Runner session");const t=yield fetch(n),s=yield t.json();if(!t.ok){this.logger.error("Non-OK response when trying to ping active Runner session. Will try again in 3s",t.headers,s),yield l(i);continue}for(this.session=new p(s.sessionID),this.logger.log(`Acquired session "${this.session.id}"`),this.cachedSessionID=this.session.id,this.status=m.Connected,this.conn.connect(this.session.id),this.logger.log(`Started pinging session "${this.session.id}"`);this.session;)try{yield this.session.ping(),yield l(5e3)}catch(e){this.logger.error(`Failed to ping session "${this.session.id}"`,e);break}this.logger.log(`Stopped pinging session "${null===(e=this.session)||void 0===e?void 0:e.id}"`),this.session=void 0,this.status=m.Disconnected,this.conn.close()}catch(e){this.logger.error("Failed to acquire Runner session. Will try again in 3s",e),yield l(i)}}}))}}function C(e){return function(e){const n=Array.from(e).reduce(((e,n)=>0|31*e+n.charCodeAt(0)),0);return("0000000"+(n>>>0).toString(16)).slice(-8)}(e)}class S{constructor(e,n){this.contextID=e,this.templateID=n,this.isReady=!1,this.id=`${e}_${C(n)}`,this.template=o[this.templateID]}}function y(e,{environmentID:n,template:t}){const s={type:u.RunningEnvironment.Start,payload:{environmentID:n,template:t}};e.send(s)}class E{constructor(e){this.opts=e,this.envs=[],this.logger=new r("EvaluationContext",e.debug),this.unsubscribeConnHandler=this.opts.conn.subscribeHandler({onOpen:this.handleConnectionOpen.bind(this),onMessage:this.handleConnectionMessage.bind(this),onClose:this.handleConnectionClose.bind(this)}),this.opts.conn.isOpen&&this.handleConnectionOpen(),this.opts.conn.isClosed&&this.handleConnectionClose()}get contextID(){return this.opts.contextID}handleConnectionOpen(){var e,n;this.restart(),null===(n=(e=this.opts).onSessionChange)||void 0===n||n.call(e,{status:m.Connected})}handleConnectionClose(){var e,n;null===(n=(e=this.opts).onSessionChange)||void 0===n||n.call(e,{status:m.Connecting})}restart(){var e;return null===(e=this.logger)||void 0===e||e.log("Restart - session:",this.opts.conn.sessionID),this.envs.forEach((e=>{e.isReady=!1,y(this.opts.conn,{environmentID:e.id,template:e.template})}))}destroy(){var e;null===(e=this.logger)||void 0===e||e.log("Destroy"),this.envs=[],this.unsubscribeConnHandler()}handleConnectionMessage(e){var n,t;switch(null===(n=this.logger)||void 0===n||n.log("Handling message from remote Runner",{message:e}),e.type){case u.RunningEnvironment.StartAck:{const n=e;this.vmenv_handleStartAck(n.payload);break}case u.RunningEnvironment.CmdOut:{const n=e;this.vmenv_handleCmdOut(n.payload);break}default:null===(t=this.logger)||void 0===t||t.warn("Unknown message type",{message:e})}}deleteRunningEnvironment({templateID:e}){var n;null===(n=this.logger)||void 0===n||n.log('Handling "DeleteEnvironment"',{templateID:e}),this.envs=this.envs.filter((n=>n.templateID!==e))}createRunningEnvironment({templateID:e}){var n,t,s;null===(n=this.logger)||void 0===n||n.log('Handling "CreateEnvironment"',{templateID:e});const i=this.envs.find((n=>n.templateID===e));if(i)return i;const o=new S(this.contextID,e);return this.envs=[...this.envs,o],y(this.opts.conn,{environmentID:o.id,template:o.template}),null===(s=(t=this.opts).onEnvChange)||void 0===s||s.call(t,o),o}vmenv_handleStartAck(e){var n,t,s,i;null===(n=this.logger)||void 0===n||n.log('[vmenv] Handling "StartAck"',{payload:e});const o=this.envs.find((n=>n.id===e.environmentID));o?(o.isReady=!0,null===(i=(s=this.opts).onEnvChange)||void 0===i||i.call(s,o)):null===(t=this.logger)||void 0===t||t.warn("Environment not found",{payload:e})}vmenv_handleCmdOut(e){var n,t,s;null===(n=this.logger)||void 0===n||n.log('[vmenv] Handling "CmdOut"',e),null===(s=(t=this.opts).onCmdOut)||void 0===s||s.call(t,e)}executeCommand({templateID:e,executionID:n,command:t}){var s,i,o;null===(s=this.logger)||void 0===s||s.log("Exec shell code cell",{templateID:e,executionID:n,command:t});const r=this.envs.find((n=>n.templateID===e));r?r.isReady?function(e,{environmentID:n,executionID:t,command:s}){const i={type:u.RunningEnvironment.ExecCmd,payload:{environmentID:n,executionID:t,command:s}};e.send(i)}(this.opts.conn,{environmentID:r.id,executionID:n,command:t}):null===(o=this.logger)||void 0===o||o.error("Environment is not ready",{templateID:e,executionID:n,command:t}):null===(i=this.logger)||void 0===i||i.error("Environment not found",{templateID:e,executionID:n,command:t})}}class f{constructor(){this.logger=new r("Runner"),this.conn=new g,this.sessManager=new D(this.conn)}static get obj(){return f._obj||(f._obj=new f)}get session(){return this.sessManager.session}get status(){return this.sessManager.status}reset(){this.logger.log("Reset"),this.sessManager.reset()}createContext(e){return new E(Object.assign(Object.assign({},e),{conn:this.conn}))}__debug__loadNewSession(){this.logger.log("__debug__loadNewSession"),this.sessManager.reset()}}const R=(I="1234567890abcdefghijklmnopqrstuvwxyz",b=6,()=>{let e="",n=b;for(;n--;)e+=I[Math.random()*I.length|0];return e});var I,b,k;e.DevbookStatus=void 0,(k=e.DevbookStatus||(e.DevbookStatus={}))[k.Disconnected=0]="Disconnected",k[k.Connecting=1]="Connecting",k[k.Connected=2]="Connected";class w{constructor(n){this.opts=n,this._isDestroyed=!1,this._isEnvReady=!1,this._sessionStatus=m.Disconnected,this._status=e.DevbookStatus.Disconnected;const t="default";this.contextID=t;const s=R();this.executionID=s;const i=e=>this.isEnvReady=e,o=e=>this.sessionStatus=e;this.context=f.obj.createContext({debug:n.debug,contextID:t,onEnvChange(e){i(e.isReady)},onSessionChange({status:e}){o(e)},onCmdOut(e){var t,i;e.executionID===s&&(void 0!==e.stdout&&(null===(t=n.onStdout)||void 0===t||t.call(n,e.stdout)),void 0!==e.stderr&&(null===(i=n.onStderr)||void 0===i||i.call(n,e.stderr)))}}),this.context.createRunningEnvironment({templateID:n.env})}get isDestroyed(){return this._isDestroyed}set isDestroyed(e){this._isDestroyed=e,this.updateStatus()}get isEnvReady(){return this._isEnvReady}set isEnvReady(e){this._isEnvReady=e,this.updateStatus()}get sessionStatus(){return this._sessionStatus}set sessionStatus(e){this._sessionStatus=e,this.updateStatus()}get status(){return this._status}set status(e){var n,t;this._status=e,null===(t=(n=this.opts).onStatusChange)||void 0===t||t.call(n,e)}runCmd(n){this.status!==e.DevbookStatus.Disconnected&&this.context.executeCommand({templateID:this.opts.env,executionID:this.executionID,command:n})}runCode(e){const n=o[this.opts.env].toCommand(e);this.runCmd(n)}destroy(){this.context.destroy(),this.isDestroyed=!0}updateStatus(){if(this.isDestroyed)return void(this.status!==e.DevbookStatus.Disconnected&&(this.status=e.DevbookStatus.Disconnected));let n;switch(this.sessionStatus){case m.Disconnected:n=e.DevbookStatus.Disconnected;break;case m.Connecting:n=e.DevbookStatus.Connecting;break;case m.Connected:if(!this.isEnvReady){n=e.DevbookStatus.Connecting;break}n=e.DevbookStatus.Connected}this.status=n}}e.Devbook=w,e.useDevbook=function({env:t,debug:s}){const[i,o]=n.useState(),[r,a]=n.useState(e.DevbookStatus.Disconnected),[l,c]=n.useState([]),[d,h]=n.useState([]),u=n.useCallback((e=>{i&&(h([]),c([]),i.runCmd(e))}),[i]),g=n.useCallback((e=>{i&&(h([]),c([]),i.runCode(e))}),[i]);return n.useEffect((function(){const e=new w({debug:s,env:t,onStatusChange(e){a(e)},onStderr(e){c((n=>[...n,e]))},onStdout(e){h((n=>[...n,e]))}});return h([]),c([]),o(e),()=>{e.destroy()}}),[t,s]),{stderr:l,stdout:d,runCmd:u,runCode:g,status:r}},Object.defineProperty(e,"__esModule",{value:!0})})); | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "@devbookhq/sdk", | ||
"version": "0.1.0", | ||
"version": "0.1.2", | ||
"description": "Devbook allows visitors of your docs to interact with and execute any code snippet or shell command in a private VM", | ||
"homepage": "https://usedevbook.com", | ||
"license": "SEE LICENSE IN LICENSE", | ||
"author": { | ||
@@ -43,2 +44,3 @@ "name": "FoundryLabs, Inc.", | ||
"README.md", | ||
"LICENSE", | ||
"package.json", | ||
@@ -45,0 +47,0 @@ "package-lock.json" |
@@ -12,2 +12,6 @@ # Devbook SDK | ||
## Installation | ||
```sh | ||
npm install @devbookhq/sdk | ||
``` | ||
## Usage | ||
@@ -18,6 +22,3 @@ | ||
// 1. Import the hook. | ||
import { | ||
useDevbook, | ||
Env, | ||
} from '@devbookhq/sdk' | ||
import { useDevbook, Env } from '@devbookhq/sdk' | ||
@@ -70,3 +71,3 @@ // 2. Define your code. | ||
- NodeJS | ||
- Custom environment based on a container (coming soon) | ||
- *(coming soon)* Custom container based environment | ||
@@ -73,0 +74,0 @@ ## Usage of Devbook in example apps |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Misc. License Issues
License(Experimental) A package's licensing information has fine-grained problems.
Found 1 instance in 1 package
326147
2687
74
1