New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@devbookhq/sdk

Package Overview
Dependencies
Maintainers
2
Versions
152
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@devbookhq/sdk - npm Package Compare versions

Comparing version 1.0.9 to 1.0.10

1

lib/cjs/common-ts/RunnerWebSocket/CodeCellMessage.d.ts

@@ -6,2 +6,3 @@ import { TCodeCell, BaseMessage } from './BaseMessage';

environmentID: string;
codeCellID: string;
};

@@ -8,0 +9,0 @@ }

22

lib/cjs/common-ts/RunnerWebSocket/RunningEnvironmentMessage.d.ts

@@ -22,3 +22,10 @@ import { CodeCell } from '../CodeCell';

environmentID: string;
template: TemplateConfig;
/**
* Either the `template` or the `templateID` field must be present.
*/
template?: TemplateConfig;
/**
* Either the `template` or the `templateID` field must be present.
*/
templateID?: string;
};

@@ -33,3 +40,3 @@ }

environmentID: string;
template: TemplateConfig;
template: Pick<TemplateConfig, 'id' | 'image'>;
/**

@@ -138,13 +145,2 @@ * A boolean indicating whether the environment has already existed or a new one was created.

/**
* Sent to remote Runner when a client requests to overwrite content of a file in the environment's filesystem.
*/
export interface RunningEnvironment_WriteFile extends BaseRunningEnvironment {
type: TRunningEnvironment.WriteFile;
payload: {
environmentID: string;
path: string;
content: string;
};
}
/**
* Sent to remote Runner when a client requests the content of a file in the environment's filesystem.

@@ -151,0 +147,0 @@ */

import * as runner from './runner';
import { templates, Env } from './template';
export { runner, templates, Env, };
export { runner, };

@@ -1,4 +0,7 @@

import { Env } from './constants';
import { Filesystem } from './runningEnvironment/filesystem';
/**
* Runtime environment to use with the Devbooks' VMs.
*/
export declare type Env = string;
/**
* Methods for accessing and manipulating this `Devbook`'s VM's filesystem.

@@ -40,11 +43,11 @@ */

*/
Disconnected = 0,
Disconnected = "Disconnected",
/**
* Devbook is trying to start or connect to a VM.
*/
Connecting = 1,
Connecting = "Connecting",
/**
* Devbook is connected to a VM and ready to run code or a command.
*/
Connected = 2
Connected = "Connected"
}

@@ -89,3 +92,3 @@ /**

*
* This affects which runtime (NodeJS, etc...) will be available and used in the {@link Devbook.runCode} function.
* This affects which runtime (NodeJS, etc...) will be available and used in the {@link Devbook.runCmd} function.
*

@@ -96,7 +99,7 @@ * `Devbook` instances with different environments are isolated - each has their own filesystem and process namespace.

/**
* This function will be called when this `Devbook` receives new stdout after you called {@link Devbook.runCode} or {@link Devbook.runCode}.
* This function will be called when this `Devbook` receives new stdout after you called {@link Devbook.runCmd}.
*/
onStdout?: (stdout: string) => void;
/**
* This function will be called when this `Devbook` receives new stderr after you called {@link Devbook.runCode} or {@link Devbook.runCode}.
* This function will be called when this `Devbook` receives new stderr after you called {@link Devbook.runCmd}.
*/

@@ -136,10 +139,2 @@ onStderr?: (stderr: string) => void;

/**
* Run `code` in the VM using the runtime you passed to this `Devbook`'s constructor as the `env`({@link Env}) parameter.
*
* This {@link Devboook}'s VM shares filesystem and process namespace with other `Devbook`'s with the same `env`({@link Env}) passed to their constructors.
*
* @param code Code to run
*/
runCode(code: string): void;
/**
* Disconnect this `Devbook` from the VM.

@@ -146,0 +141,0 @@ */

import * as rws from '../common-ts/RunnerWebSocket';
import { WebSocketConnection } from './webSocketConnection';
import { Env } from './constants';
import { RunningEnvironment } from './runningEnvironment';
import { SessionStatus } from './session/sessionManager';
import { Env } from './devbook';
export interface EvaluationContextOpts {

@@ -23,2 +23,3 @@ contextID: string;

private fsWriteSubscribers;
private fileContentSubscribers;
readonly env: RunningEnvironment;

@@ -49,6 +50,2 @@ private readonly unsubscribeConnHandler;

}): void;
executeCode({ executionID, code }: {
executionID: string;
code: string;
}): void;
executeCommand({ executionID, command }: {

@@ -58,2 +55,4 @@ executionID: string;

}): void;
private subscribeFileContent;
private unsubscribeFileContent;
private subscribeFSWrite;

@@ -60,0 +59,0 @@ private unsubscribeFSWrite;

@@ -1,3 +0,2 @@

export type { FS } from './devbook';
export type { FS, Env, } from './devbook';
export { default as Devbook, DevbookStatus, } from './devbook';
export { Env } from './constants';

@@ -1,4 +0,3 @@

import { TemplateConfig } from '../../common-ts/TemplateConfig';
import { Env } from '../constants';
import * as envfs from './filesystem';
import { Env } from '../devbook';
export declare enum OutputSource {

@@ -16,3 +15,2 @@ Stdout = 0,

readonly id: string;
readonly template: TemplateConfig;
output: OutputEntry[];

@@ -24,4 +22,3 @@ readonly filesystem: envfs.Filesystem;

logOutput(message: string, source: OutputSource): void;
rootDir(): string;
}
export default RunningEnvironment;

@@ -1,2 +0,2 @@

import { TemplateConfig } from '../../common-ts/TemplateConfig';
import { Env } from '../devbook';
import { WebSocketConnection } from '../webSocketConnection';

@@ -25,5 +25,5 @@ /**

}): void;
declare function start(conn: WebSocketConnection, { environmentID, template, }: {
declare function start(conn: WebSocketConnection, { environmentID, templateID, }: {
environmentID: string;
template: TemplateConfig;
templateID: Env;
}): void;

@@ -30,0 +30,0 @@ declare function execCmd(conn: WebSocketConnection, { environmentID, executionID, command, }: {

export { useDevbook } from './react';
export { Devbook, Env, DevbookStatus, } from './core';
export { Devbook, DevbookStatus, } from './core';

@@ -1,2 +0,2 @@

"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react");class t{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(`[${this.id()}]`,...e)}warn(...e){this.isEnabled&&console.warn(`[${this.id()}]`,...e)}error(...e){console.error(`[${this.id()} ERROR]`,...e)}}
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var t=require("react");class e{constructor(t,e=!1){this.logID=t,this.isEnabled=e}id(){return"function"==typeof this.logID?this.logID():this.logID}log(...t){this.isEnabled&&console.log(`[${this.id()}]`,...t)}warn(...t){this.isEnabled&&console.warn(`[${this.id()}]`,...t)}error(...t){console.error(`[${this.id()} ERROR]`,...t)}}
/*! *****************************************************************************

@@ -15,3 +15,3 @@ Copyright (c) Microsoft Corporation.

PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */function n(e,t,n,s){return new(n||(n=Promise))((function(i,o){function r(e){try{h(s.next(e))}catch(e){o(e)}}function a(e){try{h(s.throw(e))}catch(e){o(e)}}function h(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(r,a)}h((s=s.apply(e,t||[])).next())}))}function s(e){return new Promise((t=>setTimeout(t,e)))}var i,o,r;!function(e){e.Error="Runner.Error"}(i||(i={})),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",e.RunCode="RunningEnvironment.Run"}(o||(o={})),function(e){e.Error="CodeCell.Error"}(r||(r={}));const a={Runner:i,RunningEnvironment:o,CodeCell:r};var h;exports.Env=void 0,(h=exports.Env||(exports.Env={})).NextJS="nextjs-v11-components",h.NodeJS="nodejs-v16",h.Supabase="supabase",h.BananaNode="banana-node",h.BananaPython="banana-python";const l={[exports.Env.NodeJS]:{id:"nodejs-v16",fileExtension:".js",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}"`},[exports.Env.Supabase]:{id:"supabase",fileExtension:".js",image:"us-central1-docker.pkg.dev/devbookhq/devbook-runner-templates/supabase",root_dir:"/home/runner",code_cells_dir:"/home/runner/src",toCommand:e=>`node "${e}"`},[exports.Env.NextJS]:{id:"nextjs-v11-components",fileExtension:".tsx",image:"us-central1-docker.pkg.dev/devbookhq/devbook-runner-templates/nextjs-v11-components",root_dir:"/home/runner",code_cells_dir:"/home/runner/src"},[exports.Env.BananaNode]:{id:"banana-node",fileExtension:".js",image:"us-central1-docker.pkg.dev/devbookhq/devbook-runner-templates/banana-node",root_dir:"/home/runner",code_cells_dir:"/home/runner/src"},[exports.Env.BananaPython]:{id:"banana-python",fileExtension:".py",image:"us-central1-docker.pkg.dev/devbookhq/devbook-runner-templates/banana-python",root_dir:"/home/runner",code_cells_dir:"/home/runner"}};class d{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((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.sessionID),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(e){var t;this.logger.log("Connection opened",{readyState:null===(t=this.client)||void 0===t?void 0:t.readyState}),this.handlers.forEach((t=>t.onOpen(e)))}_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 n(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 s(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(a.RunningEnvironment).includes(n.type)||Object.values(a.Runner).includes(n.type)||Object.values(a.CodeCell).includes(n.type)?n.type!==a.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 c,u;!function(e){e.Ok="Ok",e.Terminated="Terminated"}(c||(c={}));class g{constructor(e,n=new Date){this.id=e,this.lastPing=n,this.logger=new t("RunnerSession"),this.url="https://orchestrator.usedevbook.com"}ping(){return n(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===c.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"}(u||(u={}));class m{constructor(e){this.conn=e,this.logger=new t("SessionManager"),this.url="https://orchestrator.usedevbook.com",this.isGettingSessionActive=!1,this.status=u.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=u.Disconnected,this.cachedSessionID=null,this.conn.close(),this.session=void 0}getSession(){var e;return n(this,void 0,void 0,(function*(){if(!this.isGettingSessionActive)for(this.isGettingSessionActive=!0;;){this.status=u.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),i=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,i),yield s(3e3);continue}for(this.session=new g(i.sessionID),this.logger.log(`Acquired session "${this.session.id}"`),this.cachedSessionID=this.session.id,this.status=u.Connected,this.conn.connect(this.session.id),this.logger.log(`Started pinging session "${this.session.id}"`);this.session;)try{yield this.session.ping(),yield s(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=u.Disconnected,this.conn.close()}catch(e){this.logger.error("Failed to acquire Runner session. Will try again in 3s",e),yield s(3e3)}}}))}}function v(e,t){for(var n=0,s=e.length-1;s>=0;s--){var i=e[s];"."===i?e.splice(s,1):".."===i?(e.splice(s,1),n++):n&&(e.splice(s,1),n--)}if(t)for(;n--;n)e.unshift("..");return e}var p=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/,f=function(e){return p.exec(e).slice(1)};function D(){for(var e="",t=!1,n=arguments.length-1;n>=-1&&!t;n--){var s=n>=0?arguments[n]:"/";if("string"!=typeof s)throw new TypeError("Arguments to path.resolve must be strings");s&&(e=s+"/"+e,t="/"===s.charAt(0))}return(t?"/":"")+(e=v(S(e.split("/"),(function(e){return!!e})),!t).join("/"))||"."}function y(e){var t=C(e),n="/"===w(e,-1);return(e=v(S(e.split("/"),(function(e){return!!e})),!t).join("/"))||t||(e="."),e&&n&&(e+="/"),(t?"/":"")+e}function C(e){return"/"===e.charAt(0)}var b={extname:function(e){return f(e)[3]},basename:function(e,t){var n=f(e)[2];return t&&n.substr(-1*t.length)===t&&(n=n.substr(0,n.length-t.length)),n},dirname:function(e){var t=f(e),n=t[0],s=t[1];return n||s?(s&&(s=s.substr(0,s.length-1)),n+s):"."},sep:"/",delimiter:":",relative:function(e,t){function n(e){for(var t=0;t<e.length&&""===e[t];t++);for(var n=e.length-1;n>=0&&""===e[n];n--);return t>n?[]:e.slice(t,n-t+1)}e=D(e).substr(1),t=D(t).substr(1);for(var s=n(e.split("/")),i=n(t.split("/")),o=Math.min(s.length,i.length),r=o,a=0;a<o;a++)if(s[a]!==i[a]){r=a;break}var h=[];for(a=r;a<s.length;a++)h.push("..");return(h=h.concat(i.slice(r))).join("/")},join:function(){var e=Array.prototype.slice.call(arguments,0);return y(S(e,(function(e,t){if("string"!=typeof e)throw new TypeError("Arguments to path.join must be strings");return e})).join("/"))},isAbsolute:C,normalize:y,resolve:D};function S(e,t){if(e.filter)return e.filter(t);for(var n=[],s=0;s<e.length;s++)t(e[s],s,e)&&n.push(e[s]);return n}var E,w="b"==="ab".substr(-1)?function(e,t,n){return e.substr(t,n)}:function(e,t,n){return t<0&&(t=e.length+t),e.substr(t,n)};class I{get level(){return b.normalize(this.path).split(b.sep).length-1}}function k(e){return e.sort(((e,t)=>"Prompt"===e.type?-2:e.type!==t.type?"Dir"===e.type?-1:"Dir"===t.type?1:0:e.key.localeCompare(t.key))),e}class x extends I{constructor({name:e,parent:t,onAddItem:n}){super(),this.children=[],this.name=e,this.parent=t,this.addItemHandler=n,this.path=b.join(this.parent.path,this.name)}removeChildNode(e){this.children=this.children.filter((t=>t!==e))}serialize(e,t,n){const s=this.children.map((s=>s.serialize(e,t,n)));return{type:"Dir",key:this.path,title:e({name:this.name,onAddFileMouseDown:e=>{this.addItemHandler({event:e,dir:this,type:"File"})},onAddDirMouseDown:e=>{this.addItemHandler({event:e,dir:this,type:"Dir"})}}),children:k(s)}}}class R extends I{constructor({name:e,parent:t}){super(),this.name=e,this.parent=t,this.path=b.join(this.parent.path,this.name)}serialize(){return{type:"File",key:this.path,title:this.name,isLeaf:!0}}}class F extends I{constructor({parent:e,forNode:t,onConfirm:n,onBlur:s}){super(),this.name="name-prompt",this.parent=e,this.forNode=t,this.path=b.join(e.path,this.name),this.onConfirm=n,this.onBlur=s}serialize(e,t,n){return{type:"Prompt",key:this.path,title:t({onConfirm:e=>{var t;return null===(t=this.onConfirm)||void 0===t?void 0:t.call(this,this,e)},onBlur:()=>{var e;return null===(e=this.onBlur)||void 0===e?void 0:e.call(this,this)}}),isLeaf:!0,selectable:!1,icon:n({type:this.forNode})}}}class _ extends I{constructor({onAddItem:e}){super(),this.name="/",this.path="/",this.parent=void 0,this.children=[],this.addItemHandler=e}serialize(e,t,n){const s=this.children.map((s=>s.serialize(e,t,n)));return{type:"Root",key:this.path,title:e({name:this.name,onAddFileMouseDown:e=>{this.addItemHandler({event:e,dir:this,type:"File"})},onAddDirMouseDown:e=>{this.addItemHandler({event:e,dir:this,type:"Dir"})}}),children:k(s)}}}class P extends I{constructor({parent:e}){super(),this.name="empty-node",this.parent=e,this.path=b.join(this.parent.path,this.name)}serialize(){return{type:"Empty",key:this.path,title:"Empty Directory",isLeaf:!0,disabled:!0}}}class N{constructor(){this.logger=new t("Filesystem"),this.root=new _({onAddItem:({event:e,dir:t,type:n})=>this.showPrompt({event:e,parent:t,type:n})}),this.startingPrintIndent=0,this.onNewItemConfirmLs=[],this.onDirsChangeLs=[],this.onFileContentLs=[],this.onShowPromptLs=[]}removeAllListeners(){this.onNewItemConfirmLs=[],this.onDirsChangeLs=[],this.onFileContentLs=[],this.onShowPromptLs=[]}addListener(e,t){switch(e){case"onNewItemConfirm":this.onNewItemConfirmLs.push(t);break;case"onDirsChange":this.onDirsChangeLs.push(t);break;case"onFileContent":this.onFileContentLs.push(t);break;case"onShowPrompt":this.onShowPromptLs.push(t);break;default:throw new Error(`Unknown event type: ${e}`)}}removeListener(e,t){switch(e){case"onNewItemConfirm":this.onNewItemConfirmLs=this.onNewItemConfirmLs.filter((e=>e!==t));break;case"onDirsChange":this.onDirsChangeLs=this.onDirsChangeLs.filter((e=>e!==t));break;case"onFileContent":this.onFileContentLs=this.onFileContentLs.filter((e=>e!==t));break;case"onShowPrompt":this.onShowPromptLs=this.onShowPromptLs.filter((e=>e!==t));break;default:throw new Error(`Unknown event type: ${e}`)}}addNodeToDir(e,t){this.logger.log("Adding node to dir",{dirPath:e,node:t});let n=this.find(e);if(n||(this.logger.log("Dir not found, will make all",{dirPath:e}),n=this.mkAll(e)),!n)throw new Error("dirNode is undefined");if(!(n instanceof _||n instanceof x))throw new Error(`Node at '${e}' is not a directory or a root node`);if(n.children.some((e=>e.name===t.name)))return;let s;s="Dir"===t.type?new x({name:t.name,parent:n,onAddItem:({event:e,dir:t,type:n})=>this.showPrompt({event:e,parent:t,type:n})}):new R({name:t.name,parent:n}),1===n.children.length&&n.children[0]instanceof P?n.children=[s]:n.children.push(s),this.notifyOnDirsChangeLs({dirPaths:[e]})}removeNodeFromDir(e,t){this.logger.log("Remove node from dir",{dirPath:e,nodeName:t.name});const n=this.find(e);if(!n)throw new Error(`No node with path '${e}'`);if(!(n instanceof _||n instanceof x))throw new Error(`Node at '${e}' is not a directory or root node`);const s=n.children.length;n.children=n.children.filter((e=>e.name!==t.name));s!==n.children.length?(0===n.children.length&&(n.children=[new P({parent:n})]),this.notifyOnDirsChangeLs({dirPaths:[e]})):this.logger.warn("Node not found in dir",{dirPath:e,nodeName:t.name})}setFileContent(e){this.logger.log("Update file content",e),this.onFileContentLs.forEach((t=>t(e)))}setDirsContent(e){this.logger.log("Set dirs content",e);for(const t of e){let e=this.find(t.dirPath);if(e||(this.logger.log("Dir not found, will make all",{dirPath:t.dirPath}),e=this.mkAll(t.dirPath)),!e)throw new Error("dirNode is undefined");if(!(e instanceof _||e instanceof x))throw new Error(`Node at '${t.dirPath}' is not a directory or a root node`);const n=e.children.find((e=>e instanceof F));if(t.content.length){const n=[];for(const s of t.content){let t;t="Dir"===s.type?new x({name:s.name,parent:e,onAddItem:({event:e,dir:t,type:n})=>this.showPrompt({event:e,parent:t,type:n})}):new R({name:s.name,parent:e}),n.push(t)}e.children=n}else e.children=[new P({parent:e})];n&&e.children.push(n)}this.notifyOnDirsChangeLs({dirPaths:e.map((e=>e.dirPath))})}showPrompt(e){const{event:t,parent:n,type:s}=e;if(this.logger.log("Show prompt",{parent:n,type:s}),n.children.some((e=>e instanceof F)))return;t.preventDefault();const i=new F({parent:n,forNode:s,onConfirm:((e,t)=>{if(this.logger.log("Prompt confirm",{prompt:e,name:t}),!t)return;const n=e.parent.path,i=b.join(e.parent.path,t);this.removeFromParent(e),this.notifyOnDirsChangeLs({dirPaths:[n]}),this.notifyOnNewItemConfirmLs({fullPath:i,name:t,type:s})}).bind(this),onBlur:(e=>{this.logger.log("Prompt blur",{prompt:e});const t=e.parent.path;this.removeFromParent(e),this.notifyOnDirsChangeLs({dirPaths:[t]})}).bind(this)});n.children.push(i),this.notifyOnDirsChangeLs({dirPaths:[i.parent.path]}),this.notifyOnShowPromptLs({dirPath:i.parent.path})}serialize(e,t,n){return this.logger.log("Serialize"),[this.root.serialize(e,t,n)]}print(e=this.root,t=this.startingPrintIndent){const n=" ".repeat(t);console.log(n+e.path,`(${e.name})`);for(const s of e.children)s instanceof x?this.print(s,t+1):console.log(n+" "+s.path,`(${s.name})`)}find(e,t=this.root){if(this.logger.log("Find (recursion)",{currentPath:t.path,targetPath:e}),e=b.normalize(e),t.path===e)return t;const n=e.split(b.sep).length-1;if(!(t.level>n)&&(t instanceof _||t instanceof x))for(const n of t.children){const t=this.find(e,n);if(t)return t}}mkDir(e){this.logger.log("Make dir",e);const t=this.find(e.parentPath);if(!t)throw new Error(`Parent dir '${e.parentPath}' not found`);if(!(t instanceof _||t instanceof x))throw new Error("Parent is not a dir or root");const n=new x({parent:t,name:e.name,onAddItem:({event:e,dir:t,type:n})=>this.showPrompt({event:e,parent:t,type:n})});return t.children.push(n),n}mkAll(e){this.logger.log("Make all",e);const t=e.split(b.sep);let n,s="/";for(const e of t)if(s=b.join(s,e),!this.find(s)){const t=b.dirname(s);n=this.mkDir({parentPath:t,name:e})}return n}removeFromParent(e){const{parent:t}=e;(t instanceof _||t instanceof x)&&(t.children=t.children.filter((t=>t!==e))),e.parent=void 0}notifyOnShowPromptLs(e){this.logger.log("Notify on show prompt",e),this.onShowPromptLs.forEach((t=>t(e)))}notifyOnNewItemConfirmLs(e){this.logger.log("Notify on new item confirm",e),this.onNewItemConfirmLs.forEach((t=>t(e)))}notifyOnDirsChangeLs(e){this.logger.log("Notify on dirs change",e),this.onDirsChangeLs.forEach((t=>t(e)))}}function L(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)}!function(e){e[e.Stdout=0]="Stdout",e[e.Stderr=1]="Stderr"}(E||(E={}));class O{constructor(e,t){this.contextID=e,this.templateID=t,this.output=[],this.filesystem=new N,this.isReady=!1,this.id=`${e}_${L(t)}`,this.template=l[this.templateID]}restart(){this.output=[],this.isReady=!1,this.filesystem.setDirsContent([{dirPath:"/",content:[]}])}logOutput(e,t){this.output=[...this.output,{message:e,source:t}]}rootDir(){return this.template.root_dir}}function $(e,{environmentID:t,template:n}){const s={type:a.RunningEnvironment.Start,payload:{environmentID:t,template:n}};e.send(s)}function j(e,{environmentID:t,executionID:n,command:s}){const i={type:a.RunningEnvironment.ExecCmd,payload:{environmentID:t,executionID:n,command:s}};e.send(i)}function A(e,{environmentID:t,path:n,content:s}){const i={type:a.RunningEnvironment.WriteFile,payload:{environmentID:t,path:n,content:s}};e.send(i)}class M{constructor(e){var n,s;this.opts=e,this.fsWriteSubscribers=[],this.logger=new t(`EvaluationContext [${e.templateID}]`,e.debug),this.env=new O(this.contextID,e.templateID),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.opts.conn.sessionID&&this.handleConnectionOpen(this.opts.conn.sessionID),this.opts.conn.isClosed&&this.handleConnectionClose(),$(this.opts.conn,{environmentID:this.env.id,template:this.env.template}),null===(s=(n=this.opts).onEnvChange)||void 0===s||s.call(n,this.env)}get contextID(){return this.opts.contextID}restart(){this.logger.log("Restart",this.opts.conn.sessionID),this.env.restart(),$(this.opts.conn,{environmentID:this.env.id,template:this.env.template})}destroy(){this.logger.log("Destroy"),this.unsubscribeConnHandler(),this.env.filesystem.removeAllListeners(),this.fsWriteSubscribers=[]}getFile({path:e}){return n(this,void 0,void 0,(function*(){let t;this.logger.log("Get file",{filepath:e});const n=new Promise(((e,n)=>{t=e,setTimeout((()=>{n("Timeout")}),1e4)})),s=n=>{n.path.endsWith(e)&&t(n.content)};this.env.filesystem.addListener("onFileContent",s),function(e,{environmentID:t,path:n}){const s={type:a.RunningEnvironment.GetFile,payload:{environmentID:t,path:n}};e.send(s)}(this.opts.conn,{environmentID:this.env.id,path:e});try{return yield n}catch(t){throw new Error(`Error retrieving file ${e}: ${t}`)}finally{this.env.filesystem.removeListener("onFileContent",s)}}))}deleteFile({path:e}){this.logger.log("Delete file",{filepath:e}),function(e,{environmentID:t,path:n}){const s={type:a.RunningEnvironment.RemoveFile,payload:{environmentID:t,path:n}};e.send(s)}(this.opts.conn,{environmentID:this.env.id,path:e})}updateFile({path:e,content:t}){return n(this,void 0,void 0,(function*(){let n;this.logger.log("Update file",{filepath:e});const s=new Promise(((e,t)=>{n=e,setTimeout((()=>{t("Timeout")}),1e4)})),i=t=>{t.path.endsWith(e)&&n()};this.subscribeFSWrite(i),A(this.opts.conn,{environmentID:this.env.id,path:e,content:t});try{yield s}catch(t){throw new Error(`File ${e} not written to VM: ${t}`)}finally{this.unsubscribeFSWrite(i)}}))}createDir({path:e}){this.logger.log("Create dir",{filepath:e}),function(e,{environmentID:t,path:n}){const s={type:a.RunningEnvironment.CreateDir,payload:{environmentID:t,path:n}};e.send(s)}(this.opts.conn,{environmentID:this.env.id,path:e})}listDir({path:e}){this.logger.log("List dir",{filepath:e}),function(e,{environmentID:t,path:n}){const s={type:a.RunningEnvironment.ListDir,payload:{environmentID:t,path:n}};e.send(s)}(this.opts.conn,{environmentID:this.env.id,path:e})}executeCode({executionID:e,code:t}){this.logger.log("Execute code",{executionID:e});const n=l[this.env.templateID];if(void 0===n.toCommand)return;const s=`${e}${n.fileExtension}`,i=b.join("/src",s);A(this.opts.conn,{environmentID:this.env.id,path:i,content:t});const o=b.join(n.root_dir,i),r=n.toCommand(o);j(this.opts.conn,{environmentID:this.env.id,executionID:e,command:r})}executeCommand({executionID:e,command:t}){this.logger.log("Execute shell command",{executionID:e,command:t}),j(this.opts.conn,{environmentID:this.env.id,executionID:e,command:t})}subscribeFSWrite(e){this.fsWriteSubscribers.push(e)}unsubscribeFSWrite(e){const t=this.fsWriteSubscribers.indexOf(e);t>-1&&this.fsWriteSubscribers.splice(t,1)}handleConnectionOpen(e){var t,n;this.restart(),null===(n=(t=this.opts).onSessionChange)||void 0===n||n.call(t,{status:u.Connected,sessionID:e})}handleConnectionClose(){var e,t;null===(t=(e=this.opts).onSessionChange)||void 0===t||t.call(e,{status:u.Connecting})}handleConnectionMessage(e){switch(this.logger.log("Handling message from remote Runner",{message:e}),e.type){case a.RunningEnvironment.StartAck:{const t=e;this.vmenv_handleStartAck(t.payload);break}case a.RunningEnvironment.CmdOut:{const t=e;this.vmenv_handleCmdOut(t.payload);break}case a.RunningEnvironment.CmdExit:{const t=e;this.vmenv_handleCmdExit(t.payload);break}case a.RunningEnvironment.FSEventWrite:{const t=e;this.vmenv_handleFSEventWrite(t.payload);break}case a.RunningEnvironment.FileContent:{const t=e;this.vmenv_handleFileContent(t.payload);break}case a.RunningEnvironment.FSEventCreate:{const t=e;this.vmenv_handleFSEventCreate(t.payload);break}case a.RunningEnvironment.FSEventRemove:{const t=e;this.vmenv_handleFSEventRemove(t.payload);break}case a.RunningEnvironment.DirContent:{const t=e;this.vmenv_handleDirContent(t.payload);break}case a.RunningEnvironment.Stderr:{const t=e;this.vmenv_handleStderr(t.payload);break}case a.RunningEnvironment.Stdout:{const t=e;this.vmenv_handleStdout(t.payload);break}default:this.logger.warn("Unknown message type",{message:e})}}vmenv_handleFSEventCreate(e){this.logger.log('[vmenv] Handling "FSEventCreate"',e);const t=b.basename(e.path),n=b.dirname(e.path),s="Directory"===e.type?"Dir":"File";this.env.filesystem.addNodeToDir(n,{name:t,type:s})}vmenv_handleFSEventRemove(e){this.logger.log('[vmenv] Handling "FSEventRemove"',{payload:e});const t=b.basename(e.path),n=b.dirname(e.path);this.env.filesystem.removeNodeFromDir(n,{name:t})}vmenv_handleDirContent(e){this.logger.log('[vmenv] Handling "DirContent"',e);const t=[];for(const n of e.content){const e=b.basename(n.path),s="Directory"===n.type?"Dir":"File";t.push({name:e,type:s})}this.env.filesystem.setDirsContent([{dirPath:e.dirPath,content:t}])}vmenv_handleCmdExit(e){var t,n;this.logger.log('[vmenv] Handling "CmdExit"',e),void 0!==e.error&&(null===(n=(t=this.opts).onCmdOut)||void 0===n||n.call(t,{environmentID:e.environmentID,executionID:e.executionID,stderr:e.error}))}vmenv_handleFSEventWrite(e){this.logger.log('[vmenv] Handling "FSEventWrite"',e),this.fsWriteSubscribers.forEach((t=>t(e)))}vmenv_handleFileContent(e){this.logger.log('[vmenv] Handling "FileContent"',{environmentID:e.environmentID,path:e.path}),this.env.filesystem.setFileContent(e)}vmenv_handleStartAck(e){var t,n;this.logger.log('[vmenv] Handling "StartAck"',{payload:e}),this.env.isReady=!0,null===(n=(t=this.opts).onEnvChange)||void 0===n||n.call(t,this.env)}vmenv_handleCmdOut(e){var t,n;this.logger.log('[vmenv] Handling "CmdOut"',e),null===(n=(t=this.opts).onCmdOut)||void 0===n||n.call(t,e)}vmenv_handleStderr(e){this.logger.log('[vmenv] Handling "Stderr"',e),this.env.logOutput(e.message,E.Stderr)}vmenv_handleStdout(e){this.logger.log('[vmenv] Handling "Stdout"',e),this.env.logOutput(e.message,E.Stdout)}}class W{constructor(){this.logger=new t("Runner"),this.conn=new d,this.sessManager=new m(this.conn)}static get obj(){return W._obj||(W._obj=new W)}get session(){return this.sessManager.session}get status(){return this.sessManager.status}reset(){this.logger.log("Reset"),this.sessManager.reset()}createContext(e){return new M(Object.assign(Object.assign({},e),{conn:this.conn}))}__debug__loadNewSession(){this.logger.log("__debug__loadNewSession"),this.sessManager.reset()}}const H=(z="1234567890abcdefghijklmnopqrstuvwxyz",T=6,()=>{let e="",t=T;for(;t--;)e+=z[Math.random()*z.length|0];return e});var z,T,q;exports.DevbookStatus=void 0,(q=exports.DevbookStatus||(exports.DevbookStatus={}))[q.Disconnected=0]="Disconnected",q[q.Connecting=1]="Connecting",q[q.Connected=2]="Connected";class G{constructor(e){this.opts=e,this.contextID="default",this.executionID=H(),this._isDestroyed=!1,this._isEnvReady=!1,this._sessionStatus=u.Disconnected,this._status=exports.DevbookStatus.Disconnected;const t=this.getURL.bind(this),n=()=>this.opts.env,s=()=>this.executionID,i=e=>this.isEnvReady=e,o=e=>this.sessionStatus=e,r=e=>this.sessionID=e;this.context=W.obj.createContext({debug:e.debug,templateID:e.env,contextID:this.contextID,onEnvChange(s){var o;s.templateID===n()&&(i(s.isReady),null===(o=e.onURLChange)||void 0===o||o.call(e,t))},onSessionChange({status:n,sessionID:s}){var i;r(s),o(n),null===(i=e.onURLChange)||void 0===i||i.call(e,t)},onCmdOut(t){var n,i;t.executionID===s()&&(void 0!==t.stdout&&(null===(n=e.onStdout)||void 0===n||n.call(e,t.stdout)),void 0!==t.stderr&&(null===(i=e.onStderr)||void 0===i||i.call(e,t.stderr)))}})}get sessionID(){return this._sessionID}set sessionID(e){this._sessionID=e}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)}get env(){return this.context.env}get fs(){const e=this.env.filesystem;return{delete:this.deleteFile.bind(this),listDir:this.listDir.bind(this),createDir:this.createDir.bind(this),get:this.getFile.bind(this),write:this.writeFile.bind(this),addListener:e.addListener.bind(e),removeListener:e.removeListener.bind(e),serialize:e.serialize.bind(e)}}getURL(e){if(this.status===exports.DevbookStatus.Connected&&this.sessionID&&this.env.isReady)return`https://${e}-${this.env.id}-${this.sessionID}.o.usedevbook.com`}runCmd(e){if(this.status!==exports.DevbookStatus.Connected)throw new Error("Not connected to the VM yet.");this.executionID=H(),this.context.executeCommand({executionID:this.executionID,command:e})}runCode(e){if(this.status!==exports.DevbookStatus.Connected)throw new Error("Not connected to the VM yet.");this.executionID=H(),this.context.executeCode({executionID:this.executionID,code:e})}destroy(){this.context.destroy(),this.isDestroyed=!0}listDir(e){if(this.status!==exports.DevbookStatus.Connected)throw new Error("Not connected to the VM yet.");return this.context.listDir({path:e})}createDir(e){if(this.status!==exports.DevbookStatus.Connected)throw new Error("Not connected to the VM yet.");return this.context.createDir({path:e})}deleteFile(e){if(this.status!==exports.DevbookStatus.Connected)throw new Error("Not connected to the VM yet.");return this.context.deleteFile({path:e})}getFile(e){if(this.status!==exports.DevbookStatus.Connected)throw new Error("Not connected to the VM yet.");return this.context.getFile({path:e})}writeFile(e,t){if(this.status!==exports.DevbookStatus.Connected)throw new Error("Not connected to the VM yet.");return this.context.updateFile({path:e,content:t})}updateStatus(){if(this.isDestroyed)return void(this.status!==exports.DevbookStatus.Disconnected&&(this.status=exports.DevbookStatus.Disconnected));let e;switch(this.sessionStatus){case u.Disconnected:e=exports.DevbookStatus.Disconnected;break;case u.Connecting:e=exports.DevbookStatus.Connecting;break;case u.Connected:if(!this.isEnvReady){e=exports.DevbookStatus.Connecting;break}e=exports.DevbookStatus.Connected}this.status=e}}exports.Devbook=G,exports.useDevbook=function({env:t,debug:n,port:s}){const[i,o]=e.useState(exports.DevbookStatus.Disconnected),[r,a]=e.useState([]),[h,l]=e.useState([]),[d,c]=e.useState(),u=e.useMemo((()=>(l([]),a([]),c(void 0),new G({debug:n,env:t,onStatusChange(e){o(e)},onStderr(e){a((t=>[...t,e]))},onStdout(e){l((t=>[...t,e]))},onURLChange(e){s&&c(e(s))}}))),[t,n,s]),g=e.useCallback((e=>{l([]),a([]),u.runCmd(e)}),[u]),m=e.useCallback((e=>{l([]),a([]),u.runCode(e)}),[u]);return e.useEffect((function(){return()=>u.destroy()}),[u]),{stderr:r,stdout:h,runCmd:g,runCode:m,status:i,fs:u.fs,url:d}};
***************************************************************************** */function n(t,e,n,s){return new(n||(n=Promise))((function(i,o){function r(t){try{h(s.next(t))}catch(t){o(t)}}function a(t){try{h(s.throw(t))}catch(t){o(t)}}function h(t){var e;t.done?i(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(r,a)}h((s=s.apply(t,e||[])).next())}))}function s(t){return new Promise((e=>setTimeout(e,t)))}var i,o,r;!function(t){t.Error="Runner.Error"}(i||(i={})),function(t){t.Start="RunningEnvironment.Start",t.StartAck="RunningEnvironment.StartAck",t.Eval="RunningEnvironment.Eval",t.FSEventCreate="RunningEnvironment.FSEventCreate",t.FSEventRemove="RunningEnvironment.FSEventRemove",t.FSEventWrite="RunningEnvironment.FSEventWrite",t.CreateDir="RunningEnvironment.CreateDir",t.ListDir="RunningEnvironment.ListDir",t.WriteFile="RunningEnvironment.WriteFile",t.GetFile="RunningEnvironment.GetFile",t.RemoveFile="RunningEnvironment.RemoveFile",t.DirContent="RunningEnvironment.DirContent",t.FileContent="RunningEnvironment.FileContent",t.Stdout="RunningEnvironment.Stdout",t.Stderr="RunningEnvironment.Stderr",t.ExecCmd="RunningEnvironment.ExecCmd",t.KillCmd="RunningEnvironment.KillCmd",t.ListRunningCmds="RunningEnvironment.ListRunningCmds",t.CmdOut="RunningEnvironment.CmdOut",t.CmdExit="RunningEnvironment.CmdExit",t.RunningCmds="RunningEnvironment.RunningCmds",t.RunCode="RunningEnvironment.Run"}(o||(o={})),function(t){t.Error="CodeCell.Error"}(r||(r={}));const a={Runner:i,RunningEnvironment:o,CodeCell:r};class h{constructor(){this.url="wss://orchestrator.usedevbook.com",this.logger=new e("WebSocketConnection"),this.handlers=[]}get state(){var t;return null===(t=this.client)||void 0===t?void 0:t.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(t){return this.handlers.push(t),()=>{this.handlers=this.handlers.filter((e=>e!==t))}}connect(t){(!this.client||this.client.readyState!==this.client.CONNECTING&&this.client.readyState!==this.client.OPEN)&&(t||this.sessionID?(t?(this.logger.log(`Will try to connect to session "${t}"`),this.sessionID=t):!t&&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.sessionID),this.client.onmessage=t=>{this.logger.log("Received (raw)",{msg:t}),this.handleMessage(t)},this.client.onerror=t=>this.handleError(t),this.client.onclose=t=>this.handleClose(t)):this.logger.error("Cannot connect, no session ID passed to the function and no session ID saved from the previous session"))}send(t){this.client&&this.client.readyState===this.client.OPEN?(this.logger.log("Send",t),this._send(t)):this.logger.warn("Trying to send a message while not being in the `OPEN` state or without established connection, message will be discarded",t)}close(){var t;this.logger.log("Closing connection"),null===(t=this.client)||void 0===t||t.close(1e3)}handleOpen(t){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(t)))}_send(t){var e,n;null===(e=this.client)||void 0===e||e.send((n=t,JSON.stringify(n,(()=>{const t=new WeakSet;return(e,n)=>{if("object"==typeof n&&null!==n){if(t.has(n))return;t.add(n)}return n}})(),2)))}handleClose(t){return n(this,void 0,void 0,(function*(){this.logger.log("Connection closed",t),this.handlers.forEach((t=>t.onClose())),this.logger.log("Will try to reconnect in 3s"),yield s(3e3),this.connect()}))}handleError(t){var e;this.logger.error("Connection error",t),null===(e=this.client)||void 0===e||e.close()}handleMessage(t){if(!t.data)return void this.logger.error("Message has empty data field",t);const e=JSON.parse(t.data);if(!e.type)return void this.logger.error("Message has no type",e);const n=e;Object.values(a.RunningEnvironment).includes(n.type)||Object.values(a.Runner).includes(n.type)||Object.values(a.CodeCell).includes(n.type)?n.type!==a.Runner.Error?(this.logger.log("Received (parsed)",n),this.handlers.forEach((t=>t.onMessage(n)))):this.logger.error("Runner error",n):this.logger.error('Message "type" field has unexpected value',n)}}var l,d;!function(t){t.Ok="Ok",t.Terminated="Terminated"}(l||(l={}));class c{constructor(t,n=new Date){this.id=t,this.lastPing=n,this.logger=new e("RunnerSession"),this.url="https://orchestrator.usedevbook.com"}ping(){return n(this,void 0,void 0,(function*(){this.logger.log(`Pinging session "${this.id}"`);const t=JSON.stringify({sessionID:this.id});try{const e=yield fetch(`${this.url}/session/ping`,{method:"POST",headers:{"Content-Type":"application/json"},body:t}),n=yield e.json();if(!e.ok)throw this.logger.error(e.headers,n),new Error("Non-OK response when trying to ping active Runner session");if(n.status===l.Terminated)throw new Error(`[keepAlive]: Session '${this.id}' is terminated`);this.lastPing=new Date}catch(t){throw this.logger.error(t),new Error("Failed to ping active Runner session")}}))}}!function(t){t.Connected="Connected",t.Connecting="Connecting",t.Disconnected="Disconnected"}(d||(d={}));class u{constructor(t){this.conn=t,this.logger=new e("SessionManager"),this.url="https://orchestrator.usedevbook.com",this.isGettingSessionActive=!1,this.status=d.Disconnected,this.logger.log("Initialize"),this.getSession()}get cachedSessionID(){return sessionStorage.getItem("dbk_sdk_session_id")}set cachedSessionID(t){null===t?(this.logger.log("Cleared last sessionID"),sessionStorage.removeItem("dbk_sdk_session_id")):(this.logger.log(`Saved sessionID "${t}" as last sessionID`),sessionStorage.setItem("dbk_sdk_session_id",t))}reset(){this.logger.log("Reset"),this.status=d.Disconnected,this.cachedSessionID=null,this.conn.close(),this.session=void 0}getSession(){var t;return n(this,void 0,void 0,(function*(){if(!this.isGettingSessionActive)for(this.isGettingSessionActive=!0;;){this.status=d.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 n=yield fetch(e),i=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,i),yield s(3e3);continue}for(this.session=new c(i.sessionID),this.logger.log(`Acquired session "${this.session.id}"`),this.cachedSessionID=this.session.id,this.status=d.Connected,this.conn.connect(this.session.id),this.logger.log(`Started pinging session "${this.session.id}"`);this.session;)try{yield this.session.ping(),yield s(5e3)}catch(t){this.logger.error(`Failed to ping session "${this.session.id}"`,t);break}this.logger.log(`Stopped pinging session "${null===(t=this.session)||void 0===t?void 0:t.id}"`),this.session=void 0,this.status=d.Disconnected,this.conn.close()}catch(t){this.logger.error("Failed to acquire Runner session. Will try again in 3s",t),yield s(3e3)}}}))}}function g(t,e){for(var n=0,s=t.length-1;s>=0;s--){var i=t[s];"."===i?t.splice(s,1):".."===i?(t.splice(s,1),n++):n&&(t.splice(s,1),n--)}if(e)for(;n--;n)t.unshift("..");return t}var m=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/,p=function(t){return m.exec(t).slice(1)};function v(){for(var t="",e=!1,n=arguments.length-1;n>=-1&&!e;n--){var s=n>=0?arguments[n]:"/";if("string"!=typeof s)throw new TypeError("Arguments to path.resolve must be strings");s&&(t=s+"/"+t,e="/"===s.charAt(0))}return(e?"/":"")+(t=g(C(t.split("/"),(function(t){return!!t})),!e).join("/"))||"."}function f(t){var e=D(t),n="/"===b(t,-1);return(t=g(C(t.split("/"),(function(t){return!!t})),!e).join("/"))||e||(t="."),t&&n&&(t+="/"),(e?"/":"")+t}function D(t){return"/"===t.charAt(0)}var y={extname:function(t){return p(t)[3]},basename:function(t,e){var n=p(t)[2];return e&&n.substr(-1*e.length)===e&&(n=n.substr(0,n.length-e.length)),n},dirname:function(t){var e=p(t),n=e[0],s=e[1];return n||s?(s&&(s=s.substr(0,s.length-1)),n+s):"."},sep:"/",delimiter:":",relative:function(t,e){function n(t){for(var e=0;e<t.length&&""===t[e];e++);for(var n=t.length-1;n>=0&&""===t[n];n--);return e>n?[]:t.slice(e,n-e+1)}t=v(t).substr(1),e=v(e).substr(1);for(var s=n(t.split("/")),i=n(e.split("/")),o=Math.min(s.length,i.length),r=o,a=0;a<o;a++)if(s[a]!==i[a]){r=a;break}var h=[];for(a=r;a<s.length;a++)h.push("..");return(h=h.concat(i.slice(r))).join("/")},join:function(){var t=Array.prototype.slice.call(arguments,0);return f(C(t,(function(t,e){if("string"!=typeof t)throw new TypeError("Arguments to path.join must be strings");return t})).join("/"))},isAbsolute:D,normalize:f,resolve:v};function C(t,e){if(t.filter)return t.filter(e);for(var n=[],s=0;s<t.length;s++)e(t[s],s,t)&&n.push(t[s]);return n}var S,b="b"==="ab".substr(-1)?function(t,e,n){return t.substr(e,n)}:function(t,e,n){return e<0&&(e=t.length+e),t.substr(e,n)};class w{get level(){return y.normalize(this.path).split(y.sep).length-1}}function E(t){return t.sort(((t,e)=>"Prompt"===t.type?-2:t.type!==e.type?"Dir"===t.type?-1:"Dir"===e.type?1:0:t.key.localeCompare(e.key))),t}class I extends w{constructor({name:t,parent:e,onAddItem:n}){super(),this.children=[],this.name=t,this.parent=e,this.addItemHandler=n,this.path=y.join(this.parent.path,this.name)}removeChildNode(t){this.children=this.children.filter((e=>e!==t))}serialize(t,e,n){const s=this.children.map((s=>s.serialize(t,e,n)));return{type:"Dir",key:this.path,title:t({name:this.name,onAddFileMouseDown:t=>{this.addItemHandler({event:t,dir:this,type:"File"})},onAddDirMouseDown:t=>{this.addItemHandler({event:t,dir:this,type:"Dir"})}}),children:E(s)}}}class R extends w{constructor({name:t,parent:e}){super(),this.name=t,this.parent=e,this.path=y.join(this.parent.path,this.name)}serialize(){return{type:"File",key:this.path,title:this.name,isLeaf:!0}}}class k extends w{constructor({parent:t,forNode:e,onConfirm:n,onBlur:s}){super(),this.name="name-prompt",this.parent=t,this.forNode=e,this.path=y.join(t.path,this.name),this.onConfirm=n,this.onBlur=s}serialize(t,e,n){return{type:"Prompt",key:this.path,title:e({onConfirm:t=>{var e;return null===(e=this.onConfirm)||void 0===e?void 0:e.call(this,this,t)},onBlur:()=>{var t;return null===(t=this.onBlur)||void 0===t?void 0:t.call(this,this)}}),isLeaf:!0,selectable:!1,icon:n({type:this.forNode})}}}class F extends w{constructor({onAddItem:t}){super(),this.name="/",this.path="/",this.parent=void 0,this.children=[],this.addItemHandler=t}serialize(t,e,n){const s=this.children.map((s=>s.serialize(t,e,n)));return{type:"Root",key:this.path,title:t({name:this.name,onAddFileMouseDown:t=>{this.addItemHandler({event:t,dir:this,type:"File"})},onAddDirMouseDown:t=>{this.addItemHandler({event:t,dir:this,type:"Dir"})}}),children:E(s)}}}class x extends w{constructor({parent:t}){super(),this.name="empty-node",this.parent=t,this.path=y.join(this.parent.path,this.name)}serialize(){return{type:"Empty",key:this.path,title:"Empty Directory",isLeaf:!0,disabled:!0}}}class P{constructor(){this.logger=new e("Filesystem"),this.root=new F({onAddItem:({event:t,dir:e,type:n})=>this.showPrompt({event:t,parent:e,type:n})}),this.startingPrintIndent=0,this.onNewItemConfirmLs=[],this.onDirsChangeLs=[],this.onFileContentLs=[],this.onShowPromptLs=[]}removeAllListeners(){this.onNewItemConfirmLs=[],this.onDirsChangeLs=[],this.onFileContentLs=[],this.onShowPromptLs=[]}addListener(t,e){switch(t){case"onNewItemConfirm":this.onNewItemConfirmLs.push(e);break;case"onDirsChange":this.onDirsChangeLs.push(e);break;case"onFileContent":this.onFileContentLs.push(e);break;case"onShowPrompt":this.onShowPromptLs.push(e);break;default:throw new Error(`Unknown event type: ${t}`)}}removeListener(t,e){switch(t){case"onNewItemConfirm":this.onNewItemConfirmLs=this.onNewItemConfirmLs.filter((t=>t!==e));break;case"onDirsChange":this.onDirsChangeLs=this.onDirsChangeLs.filter((t=>t!==e));break;case"onFileContent":this.onFileContentLs=this.onFileContentLs.filter((t=>t!==e));break;case"onShowPrompt":this.onShowPromptLs=this.onShowPromptLs.filter((t=>t!==e));break;default:throw new Error(`Unknown event type: ${t}`)}}addNodeToDir(t,e){this.logger.log("Adding node to dir",{dirPath:t,node:e});let n=this.find(t);if(n||(this.logger.log("Dir not found, will make all",{dirPath:t}),n=this.mkAll(t)),!n)throw new Error("dirNode is undefined");if(!(n instanceof F||n instanceof I))throw new Error(`Node at '${t}' is not a directory or a root node`);if(n.children.some((t=>t.name===e.name)))return;let s;s="Dir"===e.type?new I({name:e.name,parent:n,onAddItem:({event:t,dir:e,type:n})=>this.showPrompt({event:t,parent:e,type:n})}):new R({name:e.name,parent:n}),1===n.children.length&&n.children[0]instanceof x?n.children=[s]:n.children.push(s),this.notifyOnDirsChangeLs({dirPaths:[t]})}removeNodeFromDir(t,e){this.logger.log("Remove node from dir",{dirPath:t,nodeName:e.name});const n=this.find(t);if(!n)throw new Error(`No node with path '${t}'`);if(!(n instanceof F||n instanceof I))throw new Error(`Node at '${t}' is not a directory or root node`);const s=n.children.length;n.children=n.children.filter((t=>t.name!==e.name));s!==n.children.length?(0===n.children.length&&(n.children=[new x({parent:n})]),this.notifyOnDirsChangeLs({dirPaths:[t]})):this.logger.warn("Node not found in dir",{dirPath:t,nodeName:e.name})}setFileContent(t){this.logger.log("Update file content",t),this.onFileContentLs.forEach((e=>e(t)))}setDirsContent(t){this.logger.log("Set dirs content",t);for(const e of t){let t=this.find(e.dirPath);if(t||(this.logger.log("Dir not found, will make all",{dirPath:e.dirPath}),t=this.mkAll(e.dirPath)),!t)throw new Error("dirNode is undefined");if(!(t instanceof F||t instanceof I))throw new Error(`Node at '${e.dirPath}' is not a directory or a root node`);const n=t.children.find((t=>t instanceof k));if(e.content.length){const n=[];for(const s of e.content){let e;e="Dir"===s.type?new I({name:s.name,parent:t,onAddItem:({event:t,dir:e,type:n})=>this.showPrompt({event:t,parent:e,type:n})}):new R({name:s.name,parent:t}),n.push(e)}t.children=n}else t.children=[new x({parent:t})];n&&t.children.push(n)}this.notifyOnDirsChangeLs({dirPaths:t.map((t=>t.dirPath))})}showPrompt(t){const{event:e,parent:n,type:s}=t;if(this.logger.log("Show prompt",{parent:n,type:s}),n.children.some((t=>t instanceof k)))return;e.preventDefault();const i=new k({parent:n,forNode:s,onConfirm:((t,e)=>{if(this.logger.log("Prompt confirm",{prompt:t,name:e}),!e)return;const n=t.parent.path,i=y.join(t.parent.path,e);this.removeFromParent(t),this.notifyOnDirsChangeLs({dirPaths:[n]}),this.notifyOnNewItemConfirmLs({fullPath:i,name:e,type:s})}).bind(this),onBlur:(t=>{this.logger.log("Prompt blur",{prompt:t});const e=t.parent.path;this.removeFromParent(t),this.notifyOnDirsChangeLs({dirPaths:[e]})}).bind(this)});n.children.push(i),this.notifyOnDirsChangeLs({dirPaths:[i.parent.path]}),this.notifyOnShowPromptLs({dirPath:i.parent.path})}serialize(t,e,n){return this.logger.log("Serialize"),[this.root.serialize(t,e,n)]}print(t=this.root,e=this.startingPrintIndent){const n=" ".repeat(e);console.log(n+t.path,`(${t.name})`);for(const s of t.children)s instanceof I?this.print(s,e+1):console.log(n+" "+s.path,`(${s.name})`)}find(t,e=this.root){if(this.logger.log("Find (recursion)",{currentPath:e.path,targetPath:t}),t=y.normalize(t),e.path===t)return e;const n=t.split(y.sep).length-1;if(!(e.level>n)&&(e instanceof F||e instanceof I))for(const n of e.children){const e=this.find(t,n);if(e)return e}}mkDir(t){this.logger.log("Make dir",t);const e=this.find(t.parentPath);if(!e)throw new Error(`Parent dir '${t.parentPath}' not found`);if(!(e instanceof F||e instanceof I))throw new Error("Parent is not a dir or root");const n=new I({parent:e,name:t.name,onAddItem:({event:t,dir:e,type:n})=>this.showPrompt({event:t,parent:e,type:n})});return e.children.push(n),n}mkAll(t){this.logger.log("Make all",t);const e=t.split(y.sep);let n,s="/";for(const t of e)if(s=y.join(s,t),!this.find(s)){const e=y.dirname(s);n=this.mkDir({parentPath:e,name:t})}return n}removeFromParent(t){const{parent:e}=t;(e instanceof F||e instanceof I)&&(e.children=e.children.filter((e=>e!==t))),t.parent=void 0}notifyOnShowPromptLs(t){this.logger.log("Notify on show prompt",t),this.onShowPromptLs.forEach((e=>e(t)))}notifyOnNewItemConfirmLs(t){this.logger.log("Notify on new item confirm",t),this.onNewItemConfirmLs.forEach((e=>e(t)))}notifyOnDirsChangeLs(t){this.logger.log("Notify on dirs change",t),this.onDirsChangeLs.forEach((e=>e(t)))}}function L(t){return function(t){const e=Array.from(t).reduce(((t,e)=>0|31*t+e.charCodeAt(0)),0);return("0000000"+(e>>>0).toString(16)).slice(-8)}(t)}!function(t){t[t.Stdout=0]="Stdout",t[t.Stderr=1]="Stderr"}(S||(S={}));class _{constructor(t,e){this.contextID=t,this.templateID=e,this.output=[],this.filesystem=new P,this.isReady=!1,this.id=`${t}_${L(e)}`}restart(){this.output=[],this.isReady=!1,this.filesystem.setDirsContent([{dirPath:"/",content:[]}])}logOutput(t,e){this.output=[...this.output,{message:t,source:e}]}}function O(t,{environmentID:e,templateID:n}){const s={type:a.RunningEnvironment.Start,payload:{environmentID:e,templateID:n}};t.send(s)}class N{constructor(t){var n,s;this.opts=t,this.fsWriteSubscribers=[],this.fileContentSubscribers=[],this.logger=new e(`EvaluationContext [${t.templateID}]`,t.debug),this.env=new _(this.contextID,t.templateID);this.unsubscribeConnHandler=this.opts.conn.subscribeHandler({onOpen:t=>this.handleConnectionOpen(t),onMessage:t=>this.handleConnectionMessage(t),onClose:()=>this.handleConnectionClose()}),this.opts.conn.isOpen&&this.opts.conn.sessionID&&this.handleConnectionOpen(this.opts.conn.sessionID),this.opts.conn.isClosed&&this.handleConnectionClose(),O(this.opts.conn,{environmentID:this.env.id,templateID:this.env.templateID}),null===(s=(n=this.opts).onEnvChange)||void 0===s||s.call(n,this.env)}get contextID(){return this.opts.contextID}restart(){this.logger.log("Restart",this.opts.conn.sessionID),this.env.restart(),O(this.opts.conn,{environmentID:this.env.id,templateID:this.env.templateID})}destroy(){this.logger.log("Destroy"),this.unsubscribeConnHandler(),this.fsWriteSubscribers=[],this.fileContentSubscribers=[]}getFile({path:t}){return n(this,void 0,void 0,(function*(){let e;this.logger.log("Get file",{filepath:t});const n=new Promise(((t,n)=>{e=t,setTimeout((()=>{n("Timeout")}),1e4)})),s=n=>{n.path.endsWith(t)&&e(n.content)};this.subscribeFileContent(s),function(t,{environmentID:e,path:n}){const s={type:a.RunningEnvironment.GetFile,payload:{environmentID:e,path:n}};t.send(s)}(this.opts.conn,{environmentID:this.env.id,path:t});try{return yield n}catch(e){throw new Error(`Error retrieving file ${t}: ${e}`)}finally{this.unsubscribeFileContent(s)}}))}deleteFile({path:t}){this.logger.log("Delete file",{filepath:t}),function(t,{environmentID:e,path:n}){const s={type:a.RunningEnvironment.RemoveFile,payload:{environmentID:e,path:n}};t.send(s)}(this.opts.conn,{environmentID:this.env.id,path:t})}updateFile({path:t,content:e}){return n(this,void 0,void 0,(function*(){let n;this.logger.log("Update file",{filepath:t});const s=new Promise(((t,e)=>{n=t,setTimeout((()=>{e("Timeout")}),1e4)})),i=e=>{e.path.endsWith(t)&&n()};this.subscribeFSWrite(i),function(t,{environmentID:e,path:n,content:s}){const i={type:a.RunningEnvironment.WriteFile,payload:{environmentID:e,path:n,content:s}};t.send(i)}(this.opts.conn,{environmentID:this.env.id,path:t,content:e});try{yield s}catch(e){throw new Error(`File ${t} not written to VM: ${e}`)}finally{this.unsubscribeFSWrite(i)}}))}createDir({path:t}){this.logger.log("Create dir",{filepath:t}),function(t,{environmentID:e,path:n}){const s={type:a.RunningEnvironment.CreateDir,payload:{environmentID:e,path:n}};t.send(s)}(this.opts.conn,{environmentID:this.env.id,path:t})}listDir({path:t}){this.logger.log("List dir",{filepath:t}),function(t,{environmentID:e,path:n}){const s={type:a.RunningEnvironment.ListDir,payload:{environmentID:e,path:n}};t.send(s)}(this.opts.conn,{environmentID:this.env.id,path:t})}executeCommand({executionID:t,command:e}){this.logger.log("Execute shell command",{executionID:t,command:e}),function(t,{environmentID:e,executionID:n,command:s}){const i={type:a.RunningEnvironment.ExecCmd,payload:{environmentID:e,executionID:n,command:s}};t.send(i)}(this.opts.conn,{environmentID:this.env.id,executionID:t,command:e})}subscribeFileContent(t){this.fileContentSubscribers.push(t)}unsubscribeFileContent(t){const e=this.fileContentSubscribers.indexOf(t);e>-1&&this.fileContentSubscribers.splice(e,1)}subscribeFSWrite(t){this.fsWriteSubscribers.push(t)}unsubscribeFSWrite(t){const e=this.fsWriteSubscribers.indexOf(t);e>-1&&this.fsWriteSubscribers.splice(e,1)}handleConnectionOpen(t){var e,n;this.restart(),null===(n=(e=this.opts).onSessionChange)||void 0===n||n.call(e,{status:d.Connected,sessionID:t})}handleConnectionClose(){var t,e;null===(e=(t=this.opts).onSessionChange)||void 0===e||e.call(t,{status:d.Connecting})}handleConnectionMessage(t){switch(this.logger.log("Handling message from remote Runner",{message:t}),t.type){case a.RunningEnvironment.StartAck:{const e=t;this.vmenv_handleStartAck(e.payload);break}case a.RunningEnvironment.CmdOut:{const e=t;this.vmenv_handleCmdOut(e.payload);break}case a.RunningEnvironment.CmdExit:{const e=t;this.vmenv_handleCmdExit(e.payload);break}case a.RunningEnvironment.FSEventWrite:{const e=t;this.vmenv_handleFSEventWrite(e.payload);break}case a.RunningEnvironment.FileContent:{const e=t;this.vmenv_handleFileContent(e.payload);break}case a.RunningEnvironment.FSEventCreate:{const e=t;this.vmenv_handleFSEventCreate(e.payload);break}case a.RunningEnvironment.FSEventRemove:{const e=t;this.vmenv_handleFSEventRemove(e.payload);break}case a.RunningEnvironment.DirContent:{const e=t;this.vmenv_handleDirContent(e.payload);break}case a.RunningEnvironment.Stderr:{const e=t;this.vmenv_handleStderr(e.payload);break}case a.RunningEnvironment.Stdout:{const e=t;this.vmenv_handleStdout(e.payload);break}default:this.logger.warn("Unknown message type",{message:t})}}vmenv_handleFSEventCreate(t){this.logger.log('[vmenv] Handling "FSEventCreate"',t);const e=y.basename(t.path),n=y.dirname(t.path),s="Directory"===t.type?"Dir":"File";this.env.filesystem.addNodeToDir(n,{name:e,type:s})}vmenv_handleFSEventRemove(t){this.logger.log('[vmenv] Handling "FSEventRemove"',{payload:t});const e=y.basename(t.path),n=y.dirname(t.path);this.env.filesystem.removeNodeFromDir(n,{name:e})}vmenv_handleDirContent(t){this.logger.log('[vmenv] Handling "DirContent"',t);const e=[];for(const n of t.content){const t=y.basename(n.path),s="Directory"===n.type?"Dir":"File";e.push({name:t,type:s})}this.env.filesystem.setDirsContent([{dirPath:t.dirPath,content:e}])}vmenv_handleCmdExit(t){var e,n;this.logger.log('[vmenv] Handling "CmdExit"',t),void 0!==t.error&&(null===(n=(e=this.opts).onCmdOut)||void 0===n||n.call(e,{environmentID:t.environmentID,executionID:t.executionID,stderr:t.error}))}vmenv_handleFSEventWrite(t){this.logger.log('[vmenv] Handling "FSEventWrite"',t),this.fsWriteSubscribers.forEach((e=>e(t)))}vmenv_handleFileContent(t){this.logger.log('[vmenv] Handling "FileContent"',{environmentID:t.environmentID,path:t.path}),this.fileContentSubscribers.forEach((e=>e(t)))}vmenv_handleStartAck(t){var e,n;this.logger.log('[vmenv] Handling "StartAck"',{payload:t}),this.env.isReady=!0,null===(n=(e=this.opts).onEnvChange)||void 0===n||n.call(e,this.env)}vmenv_handleCmdOut(t){var e,n;this.logger.log('[vmenv] Handling "CmdOut"',t),null===(n=(e=this.opts).onCmdOut)||void 0===n||n.call(e,t)}vmenv_handleStderr(t){this.logger.log('[vmenv] Handling "Stderr"',t),this.env.logOutput(t.message,S.Stderr)}vmenv_handleStdout(t){this.logger.log('[vmenv] Handling "Stdout"',t),this.env.logOutput(t.message,S.Stdout)}}class ${constructor(){this.logger=new e("Runner"),this.conn=new h,this.sessManager=new u(this.conn)}static get obj(){return $._obj||($._obj=new $)}get session(){return this.sessManager.session}get status(){return this.sessManager.status}reset(){this.logger.log("Reset"),this.sessManager.reset()}createContext(t){return new N(Object.assign(Object.assign({},t),{conn:this.conn}))}__debug__loadNewSession(){this.logger.log("__debug__loadNewSession"),this.sessManager.reset()}}const A=(M="1234567890abcdefghijklmnopqrstuvwxyz",W=6,()=>{let t="",e=W;for(;e--;)t+=M[Math.random()*M.length|0];return t});var M,W,j;exports.DevbookStatus=void 0,(j=exports.DevbookStatus||(exports.DevbookStatus={})).Disconnected="Disconnected",j.Connecting="Connecting",j.Connected="Connected";class H{constructor(t){this.opts=t,this.contextID="default",this.executionID=A(),this._isDestroyed=!1,this._isEnvReady=!1,this._sessionStatus=d.Disconnected,this._status=exports.DevbookStatus.Disconnected;const e=this.getURL.bind(this),n=()=>this.opts.env,s=()=>this.executionID,i=t=>this.isEnvReady=t,o=t=>this.sessionStatus=t,r=t=>this.sessionID=t;this.context=$.obj.createContext({debug:t.debug,templateID:t.env,contextID:this.contextID,onEnvChange(s){var o;s.templateID===n()&&(i(s.isReady),null===(o=t.onURLChange)||void 0===o||o.call(t,e))},onSessionChange({status:n,sessionID:s}){var i;r(s),o(n),null===(i=t.onURLChange)||void 0===i||i.call(t,e)},onCmdOut(e){var n,i;e.executionID===s()&&(void 0!==e.stdout&&(null===(n=t.onStdout)||void 0===n||n.call(t,e.stdout)),void 0!==e.stderr&&(null===(i=t.onStderr)||void 0===i||i.call(t,e.stderr)))}})}get sessionID(){return this._sessionID}set sessionID(t){this._sessionID=t}get isDestroyed(){return this._isDestroyed}set isDestroyed(t){this._isDestroyed=t,this.updateStatus()}get isEnvReady(){return this._isEnvReady}set isEnvReady(t){this._isEnvReady=t,this.updateStatus()}get sessionStatus(){return this._sessionStatus}set sessionStatus(t){this._sessionStatus=t,this.updateStatus()}get status(){return this._status}set status(t){var e,n;this._status=t,null===(n=(e=this.opts).onStatusChange)||void 0===n||n.call(e,t)}get env(){return this.context.env}get fs(){const t=this.env.filesystem;return{delete:this.deleteFile.bind(this),listDir:this.listDir.bind(this),createDir:this.createDir.bind(this),get:this.getFile.bind(this),write:this.writeFile.bind(this),addListener:t.addListener.bind(t),removeListener:t.removeListener.bind(t),serialize:t.serialize.bind(t)}}getURL(t){if(this.status===exports.DevbookStatus.Connected&&this.sessionID&&this.env.isReady)return`https://${t}-${this.env.id}-${this.sessionID}.o.usedevbook.com`}runCmd(t){if(this.status!==exports.DevbookStatus.Connected)throw new Error("Not connected to the VM yet.");this.executionID=A(),this.context.executeCommand({executionID:this.executionID,command:t})}destroy(){this.context.destroy(),this.isDestroyed=!0}listDir(t){if(this.status!==exports.DevbookStatus.Connected)throw new Error("Not connected to the VM yet.");return this.context.listDir({path:t})}createDir(t){if(this.status!==exports.DevbookStatus.Connected)throw new Error("Not connected to the VM yet.");return this.context.createDir({path:t})}deleteFile(t){if(this.status!==exports.DevbookStatus.Connected)throw new Error("Not connected to the VM yet.");return this.context.deleteFile({path:t})}getFile(t){if(this.status!==exports.DevbookStatus.Connected)throw new Error("Not connected to the VM yet.");return this.context.getFile({path:t})}writeFile(t,e){if(this.status!==exports.DevbookStatus.Connected)throw new Error("Not connected to the VM yet.");return this.context.updateFile({path:t,content:e})}updateStatus(){if(this.isDestroyed)return void(this.status!==exports.DevbookStatus.Disconnected&&(this.status=exports.DevbookStatus.Disconnected));let t;switch(this.sessionStatus){case d.Disconnected:t=exports.DevbookStatus.Disconnected;break;case d.Connecting:t=exports.DevbookStatus.Connecting;break;case d.Connected:if(!this.isEnvReady){t=exports.DevbookStatus.Connecting;break}t=exports.DevbookStatus.Connected}this.status=t}}exports.Devbook=H,exports.useDevbook=function({env:e,debug:n,port:s}){const[i,o]=t.useState(),[r,a]=t.useState(exports.DevbookStatus.Disconnected),[h,l]=t.useState([]),[d,c]=t.useState([]),[u,g]=t.useState(),m=t.useCallback((t=>{i&&(c([]),l([]),i.runCmd(t))}),[i]);return t.useEffect((function(){const t=new H({debug:n,env:e,onStatusChange(t){a(t)},onStderr(t){l((e=>[...e,t]))},onStdout(t){c((e=>[...e,t]))},onURLChange(t){s&&g(t(s))}});return c([]),l([]),g(void 0),o(t),()=>{t.destroy()}}),[e,n,s]),{stderr:h,stdout:d,runCmd:m,status:r,fs:null==i?void 0:i.fs,url:u}};
//# sourceMappingURL=index.js.map

@@ -9,3 +9,3 @@ import { DevbookStatus, Env, FS } from '../core';

*
* This affects which runtime (NodeJS, etc.,...) will be available and used in the {@link State.runCode} function.
* This affects which runtime (NodeJS, etc.,...) will be available and used in the {@link State.runCmd} function.
*

@@ -30,11 +30,11 @@ * {@link useDevbook} hooks with different environments are isolated - each has their own filesystem and process namespace.

/**
* Stderr from the last code or command run with {@link State.runCode} or {@link State.runCmd}.
* Stderr from the last command run with {@link State.runCmd}.
*
* This array is reset when you call {@link State.runCode} or {@link State.runCmd}.
* This array is reset when you call {@link State.runCmd}.
*/
stderr: string[];
/**
* Stdout from the last code or command run with {@link State.runCode} or {@link State.runCmd}.
* Stdout from the command run with {@link State.runCmd}.
*
* This array is reset when you call {@link State.runCode} or {@link State.runCmd}.
* This array is reset when you call {@link State.runCmd}.
*/

@@ -47,10 +47,2 @@ stdout: string[];

/**
* Run `code` in the VM using the runtime you passed to this {@link useDevbook} hook as the `env`({@link Env}) parameter.
*
* This Devbook's VM shares filesystem and process namespace with other Devbooks that were created by passing the same `env`({@link Env}) to the {@link useDevbook} hooks.
*
* @param code Code to run
*/
runCode: (code: string) => void;
/**
* Run `command` in the VM.

@@ -66,3 +58,3 @@ *

*/
fs: FS;
fs?: FS;
/**

@@ -77,3 +69,3 @@ * URL address that allows you to connect to a port ({@link Opts.port})

*
* This hook exposes functions for running code ({@link State.runCode}) and commands ({@link State.runCmd}) while managing
* This hook exposes functions for running commands ({@link State.runCmd}) while managing
* {@link State.stderr}, {@link State.stdout}, and {@link State.status} - reloading the component when these fields change.

@@ -80,0 +72,0 @@ */

@@ -6,2 +6,3 @@ import { TCodeCell, BaseMessage } from './BaseMessage';

environmentID: string;
codeCellID: string;
};

@@ -8,0 +9,0 @@ }

@@ -22,3 +22,10 @@ import { CodeCell } from '../CodeCell';

environmentID: string;
template: TemplateConfig;
/**
* Either the `template` or the `templateID` field must be present.
*/
template?: TemplateConfig;
/**
* Either the `template` or the `templateID` field must be present.
*/
templateID?: string;
};

@@ -33,3 +40,3 @@ }

environmentID: string;
template: TemplateConfig;
template: Pick<TemplateConfig, 'id' | 'image'>;
/**

@@ -138,13 +145,2 @@ * A boolean indicating whether the environment has already existed or a new one was created.

/**
* Sent to remote Runner when a client requests to overwrite content of a file in the environment's filesystem.
*/
export interface RunningEnvironment_WriteFile extends BaseRunningEnvironment {
type: TRunningEnvironment.WriteFile;
payload: {
environmentID: string;
path: string;
content: string;
};
}
/**
* Sent to remote Runner when a client requests the content of a file in the environment's filesystem.

@@ -151,0 +147,0 @@ */

import * as runner from './runner';
import { templates, Env } from './template';
export { runner, templates, Env, };
export { runner, };

@@ -1,4 +0,7 @@

import { Env } from './constants';
import { Filesystem } from './runningEnvironment/filesystem';
/**
* Runtime environment to use with the Devbooks' VMs.
*/
export declare type Env = string;
/**
* Methods for accessing and manipulating this `Devbook`'s VM's filesystem.

@@ -40,11 +43,11 @@ */

*/
Disconnected = 0,
Disconnected = "Disconnected",
/**
* Devbook is trying to start or connect to a VM.
*/
Connecting = 1,
Connecting = "Connecting",
/**
* Devbook is connected to a VM and ready to run code or a command.
*/
Connected = 2
Connected = "Connected"
}

@@ -89,3 +92,3 @@ /**

*
* This affects which runtime (NodeJS, etc...) will be available and used in the {@link Devbook.runCode} function.
* This affects which runtime (NodeJS, etc...) will be available and used in the {@link Devbook.runCmd} function.
*

@@ -96,7 +99,7 @@ * `Devbook` instances with different environments are isolated - each has their own filesystem and process namespace.

/**
* This function will be called when this `Devbook` receives new stdout after you called {@link Devbook.runCode} or {@link Devbook.runCode}.
* This function will be called when this `Devbook` receives new stdout after you called {@link Devbook.runCmd}.
*/
onStdout?: (stdout: string) => void;
/**
* This function will be called when this `Devbook` receives new stderr after you called {@link Devbook.runCode} or {@link Devbook.runCode}.
* This function will be called when this `Devbook` receives new stderr after you called {@link Devbook.runCmd}.
*/

@@ -136,10 +139,2 @@ onStderr?: (stderr: string) => void;

/**
* Run `code` in the VM using the runtime you passed to this `Devbook`'s constructor as the `env`({@link Env}) parameter.
*
* This {@link Devboook}'s VM shares filesystem and process namespace with other `Devbook`'s with the same `env`({@link Env}) passed to their constructors.
*
* @param code Code to run
*/
runCode(code: string): void;
/**
* Disconnect this `Devbook` from the VM.

@@ -146,0 +141,0 @@ */

import * as rws from '../common-ts/RunnerWebSocket';
import { WebSocketConnection } from './webSocketConnection';
import { Env } from './constants';
import { RunningEnvironment } from './runningEnvironment';
import { SessionStatus } from './session/sessionManager';
import { Env } from './devbook';
export interface EvaluationContextOpts {

@@ -23,2 +23,3 @@ contextID: string;

private fsWriteSubscribers;
private fileContentSubscribers;
readonly env: RunningEnvironment;

@@ -49,6 +50,2 @@ private readonly unsubscribeConnHandler;

}): void;
executeCode({ executionID, code }: {
executionID: string;
code: string;
}): void;
executeCommand({ executionID, command }: {

@@ -58,2 +55,4 @@ executionID: string;

}): void;
private subscribeFileContent;
private unsubscribeFileContent;
private subscribeFSWrite;

@@ -60,0 +59,0 @@ private unsubscribeFSWrite;

@@ -1,3 +0,2 @@

export type { FS } from './devbook';
export type { FS, Env, } from './devbook';
export { default as Devbook, DevbookStatus, } from './devbook';
export { Env } from './constants';

@@ -1,4 +0,3 @@

import { TemplateConfig } from '../../common-ts/TemplateConfig';
import { Env } from '../constants';
import * as envfs from './filesystem';
import { Env } from '../devbook';
export declare enum OutputSource {

@@ -16,3 +15,2 @@ Stdout = 0,

readonly id: string;
readonly template: TemplateConfig;
output: OutputEntry[];

@@ -24,4 +22,3 @@ readonly filesystem: envfs.Filesystem;

logOutput(message: string, source: OutputSource): void;
rootDir(): string;
}
export default RunningEnvironment;

@@ -1,2 +0,2 @@

import { TemplateConfig } from '../../common-ts/TemplateConfig';
import { Env } from '../devbook';
import { WebSocketConnection } from '../webSocketConnection';

@@ -25,5 +25,5 @@ /**

}): void;
declare function start(conn: WebSocketConnection, { environmentID, template, }: {
declare function start(conn: WebSocketConnection, { environmentID, templateID, }: {
environmentID: string;
template: TemplateConfig;
templateID: Env;
}): void;

@@ -30,0 +30,0 @@ declare function execCmd(conn: WebSocketConnection, { environmentID, executionID, command, }: {

export { useDevbook } from './react';
export { Devbook, Env, DevbookStatus, } from './core';
export { Devbook, DevbookStatus, } from './core';

@@ -1,2 +0,2 @@

import{useState as e,useMemo as t,useCallback as n,useEffect as i}from"react";class s{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(`[${this.id()}]`,...e)}warn(...e){this.isEnabled&&console.warn(`[${this.id()}]`,...e)}error(...e){console.error(`[${this.id()} ERROR]`,...e)}}
import{useState as e,useCallback as t,useEffect as n}from"react";class i{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(`[${this.id()}]`,...e)}warn(...e){this.isEnabled&&console.warn(`[${this.id()}]`,...e)}error(...e){console.error(`[${this.id()} ERROR]`,...e)}}
/*! *****************************************************************************

@@ -15,3 +15,3 @@ Copyright (c) Microsoft Corporation.

PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */function o(e,t,n,i){return new(n||(n=Promise))((function(s,o){function r(e){try{h(i.next(e))}catch(e){o(e)}}function a(e){try{h(i.throw(e))}catch(e){o(e)}}function h(e){var t;e.done?s(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(r,a)}h((i=i.apply(e,t||[])).next())}))}function r(e){return new Promise((t=>setTimeout(t,e)))}var a,h,l;!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",e.RunCode="RunningEnvironment.Run"}(h||(h={})),function(e){e.Error="CodeCell.Error"}(l||(l={}));const d={Runner:a,RunningEnvironment:h,CodeCell:l};var c;!function(e){e.NextJS="nextjs-v11-components",e.NodeJS="nodejs-v16",e.Supabase="supabase",e.BananaNode="banana-node",e.BananaPython="banana-python"}(c||(c={}));const u={[c.NodeJS]:{id:"nodejs-v16",fileExtension:".js",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}"`},[c.Supabase]:{id:"supabase",fileExtension:".js",image:"us-central1-docker.pkg.dev/devbookhq/devbook-runner-templates/supabase",root_dir:"/home/runner",code_cells_dir:"/home/runner/src",toCommand:e=>`node "${e}"`},[c.NextJS]:{id:"nextjs-v11-components",fileExtension:".tsx",image:"us-central1-docker.pkg.dev/devbookhq/devbook-runner-templates/nextjs-v11-components",root_dir:"/home/runner",code_cells_dir:"/home/runner/src"},[c.BananaNode]:{id:"banana-node",fileExtension:".js",image:"us-central1-docker.pkg.dev/devbookhq/devbook-runner-templates/banana-node",root_dir:"/home/runner",code_cells_dir:"/home/runner/src"},[c.BananaPython]:{id:"banana-python",fileExtension:".py",image:"us-central1-docker.pkg.dev/devbookhq/devbook-runner-templates/banana-python",root_dir:"/home/runner",code_cells_dir:"/home/runner"}};class g{constructor(){this.url="wss://orchestrator.usedevbook.com",this.logger=new s("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.sessionID),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(e){var t;this.logger.log("Connection opened",{readyState:null===(t=this.client)||void 0===t?void 0:t.readyState}),this.handlers.forEach((t=>t.onOpen(e)))}_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 o(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 r(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(d.RunningEnvironment).includes(n.type)||Object.values(d.Runner).includes(n.type)||Object.values(d.CodeCell).includes(n.type)?n.type!==d.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 m,p;!function(e){e.Ok="Ok",e.Terminated="Terminated"}(m||(m={}));class v{constructor(e,t=new Date){this.id=e,this.lastPing=t,this.logger=new s("RunnerSession"),this.url="https://orchestrator.usedevbook.com"}ping(){return o(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===m.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"}(p||(p={}));class f{constructor(e){this.conn=e,this.logger=new s("SessionManager"),this.url="https://orchestrator.usedevbook.com",this.isGettingSessionActive=!1,this.status=p.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=p.Disconnected,this.cachedSessionID=null,this.conn.close(),this.session=void 0}getSession(){var e;return o(this,void 0,void 0,(function*(){if(!this.isGettingSessionActive)for(this.isGettingSessionActive=!0;;){this.status=p.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),i=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,i),yield r(3e3);continue}for(this.session=new v(i.sessionID),this.logger.log(`Acquired session "${this.session.id}"`),this.cachedSessionID=this.session.id,this.status=p.Connected,this.conn.connect(this.session.id),this.logger.log(`Started pinging session "${this.session.id}"`);this.session;)try{yield this.session.ping(),yield r(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=p.Disconnected,this.conn.close()}catch(e){this.logger.error("Failed to acquire Runner session. Will try again in 3s",e),yield r(3e3)}}}))}}function y(e,t){for(var n=0,i=e.length-1;i>=0;i--){var s=e[i];"."===s?e.splice(i,1):".."===s?(e.splice(i,1),n++):n&&(e.splice(i,1),n--)}if(t)for(;n--;n)e.unshift("..");return e}var D=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/,C=function(e){return D.exec(e).slice(1)};function w(){for(var e="",t=!1,n=arguments.length-1;n>=-1&&!t;n--){var i=n>=0?arguments[n]:"/";if("string"!=typeof i)throw new TypeError("Arguments to path.resolve must be strings");i&&(e=i+"/"+e,t="/"===i.charAt(0))}return(t?"/":"")+(e=y(I(e.split("/"),(function(e){return!!e})),!t).join("/"))||"."}function E(e){var t=b(e),n="/"===k(e,-1);return(e=y(I(e.split("/"),(function(e){return!!e})),!t).join("/"))||t||(e="."),e&&n&&(e+="/"),(t?"/":"")+e}function b(e){return"/"===e.charAt(0)}var S={extname:function(e){return C(e)[3]},basename:function(e,t){var n=C(e)[2];return t&&n.substr(-1*t.length)===t&&(n=n.substr(0,n.length-t.length)),n},dirname:function(e){var t=C(e),n=t[0],i=t[1];return n||i?(i&&(i=i.substr(0,i.length-1)),n+i):"."},sep:"/",delimiter:":",relative:function(e,t){function n(e){for(var t=0;t<e.length&&""===e[t];t++);for(var n=e.length-1;n>=0&&""===e[n];n--);return t>n?[]:e.slice(t,n-t+1)}e=w(e).substr(1),t=w(t).substr(1);for(var i=n(e.split("/")),s=n(t.split("/")),o=Math.min(i.length,s.length),r=o,a=0;a<o;a++)if(i[a]!==s[a]){r=a;break}var h=[];for(a=r;a<i.length;a++)h.push("..");return(h=h.concat(s.slice(r))).join("/")},join:function(){var e=Array.prototype.slice.call(arguments,0);return E(I(e,(function(e,t){if("string"!=typeof e)throw new TypeError("Arguments to path.join must be strings");return e})).join("/"))},isAbsolute:b,normalize:E,resolve:w};function I(e,t){if(e.filter)return e.filter(t);for(var n=[],i=0;i<e.length;i++)t(e[i],i,e)&&n.push(e[i]);return n}var R,k="b"==="ab".substr(-1)?function(e,t,n){return e.substr(t,n)}:function(e,t,n){return t<0&&(t=e.length+t),e.substr(t,n)};class x{get level(){return S.normalize(this.path).split(S.sep).length-1}}function F(e){return e.sort(((e,t)=>"Prompt"===e.type?-2:e.type!==t.type?"Dir"===e.type?-1:"Dir"===t.type?1:0:e.key.localeCompare(t.key))),e}class _ extends x{constructor({name:e,parent:t,onAddItem:n}){super(),this.children=[],this.name=e,this.parent=t,this.addItemHandler=n,this.path=S.join(this.parent.path,this.name)}removeChildNode(e){this.children=this.children.filter((t=>t!==e))}serialize(e,t,n){const i=this.children.map((i=>i.serialize(e,t,n)));return{type:"Dir",key:this.path,title:e({name:this.name,onAddFileMouseDown:e=>{this.addItemHandler({event:e,dir:this,type:"File"})},onAddDirMouseDown:e=>{this.addItemHandler({event:e,dir:this,type:"Dir"})}}),children:F(i)}}}class P extends x{constructor({name:e,parent:t}){super(),this.name=e,this.parent=t,this.path=S.join(this.parent.path,this.name)}serialize(){return{type:"File",key:this.path,title:this.name,isLeaf:!0}}}class N extends x{constructor({parent:e,forNode:t,onConfirm:n,onBlur:i}){super(),this.name="name-prompt",this.parent=e,this.forNode=t,this.path=S.join(e.path,this.name),this.onConfirm=n,this.onBlur=i}serialize(e,t,n){return{type:"Prompt",key:this.path,title:t({onConfirm:e=>{var t;return null===(t=this.onConfirm)||void 0===t?void 0:t.call(this,this,e)},onBlur:()=>{var e;return null===(e=this.onBlur)||void 0===e?void 0:e.call(this,this)}}),isLeaf:!0,selectable:!1,icon:n({type:this.forNode})}}}class L extends x{constructor({onAddItem:e}){super(),this.name="/",this.path="/",this.parent=void 0,this.children=[],this.addItemHandler=e}serialize(e,t,n){const i=this.children.map((i=>i.serialize(e,t,n)));return{type:"Root",key:this.path,title:e({name:this.name,onAddFileMouseDown:e=>{this.addItemHandler({event:e,dir:this,type:"File"})},onAddDirMouseDown:e=>{this.addItemHandler({event:e,dir:this,type:"Dir"})}}),children:F(i)}}}class O extends x{constructor({parent:e}){super(),this.name="empty-node",this.parent=e,this.path=S.join(this.parent.path,this.name)}serialize(){return{type:"Empty",key:this.path,title:"Empty Directory",isLeaf:!0,disabled:!0}}}class ${constructor(){this.logger=new s("Filesystem"),this.root=new L({onAddItem:({event:e,dir:t,type:n})=>this.showPrompt({event:e,parent:t,type:n})}),this.startingPrintIndent=0,this.onNewItemConfirmLs=[],this.onDirsChangeLs=[],this.onFileContentLs=[],this.onShowPromptLs=[]}removeAllListeners(){this.onNewItemConfirmLs=[],this.onDirsChangeLs=[],this.onFileContentLs=[],this.onShowPromptLs=[]}addListener(e,t){switch(e){case"onNewItemConfirm":this.onNewItemConfirmLs.push(t);break;case"onDirsChange":this.onDirsChangeLs.push(t);break;case"onFileContent":this.onFileContentLs.push(t);break;case"onShowPrompt":this.onShowPromptLs.push(t);break;default:throw new Error(`Unknown event type: ${e}`)}}removeListener(e,t){switch(e){case"onNewItemConfirm":this.onNewItemConfirmLs=this.onNewItemConfirmLs.filter((e=>e!==t));break;case"onDirsChange":this.onDirsChangeLs=this.onDirsChangeLs.filter((e=>e!==t));break;case"onFileContent":this.onFileContentLs=this.onFileContentLs.filter((e=>e!==t));break;case"onShowPrompt":this.onShowPromptLs=this.onShowPromptLs.filter((e=>e!==t));break;default:throw new Error(`Unknown event type: ${e}`)}}addNodeToDir(e,t){this.logger.log("Adding node to dir",{dirPath:e,node:t});let n=this.find(e);if(n||(this.logger.log("Dir not found, will make all",{dirPath:e}),n=this.mkAll(e)),!n)throw new Error("dirNode is undefined");if(!(n instanceof L||n instanceof _))throw new Error(`Node at '${e}' is not a directory or a root node`);if(n.children.some((e=>e.name===t.name)))return;let i;i="Dir"===t.type?new _({name:t.name,parent:n,onAddItem:({event:e,dir:t,type:n})=>this.showPrompt({event:e,parent:t,type:n})}):new P({name:t.name,parent:n}),1===n.children.length&&n.children[0]instanceof O?n.children=[i]:n.children.push(i),this.notifyOnDirsChangeLs({dirPaths:[e]})}removeNodeFromDir(e,t){this.logger.log("Remove node from dir",{dirPath:e,nodeName:t.name});const n=this.find(e);if(!n)throw new Error(`No node with path '${e}'`);if(!(n instanceof L||n instanceof _))throw new Error(`Node at '${e}' is not a directory or root node`);const i=n.children.length;n.children=n.children.filter((e=>e.name!==t.name));i!==n.children.length?(0===n.children.length&&(n.children=[new O({parent:n})]),this.notifyOnDirsChangeLs({dirPaths:[e]})):this.logger.warn("Node not found in dir",{dirPath:e,nodeName:t.name})}setFileContent(e){this.logger.log("Update file content",e),this.onFileContentLs.forEach((t=>t(e)))}setDirsContent(e){this.logger.log("Set dirs content",e);for(const t of e){let e=this.find(t.dirPath);if(e||(this.logger.log("Dir not found, will make all",{dirPath:t.dirPath}),e=this.mkAll(t.dirPath)),!e)throw new Error("dirNode is undefined");if(!(e instanceof L||e instanceof _))throw new Error(`Node at '${t.dirPath}' is not a directory or a root node`);const n=e.children.find((e=>e instanceof N));if(t.content.length){const n=[];for(const i of t.content){let t;t="Dir"===i.type?new _({name:i.name,parent:e,onAddItem:({event:e,dir:t,type:n})=>this.showPrompt({event:e,parent:t,type:n})}):new P({name:i.name,parent:e}),n.push(t)}e.children=n}else e.children=[new O({parent:e})];n&&e.children.push(n)}this.notifyOnDirsChangeLs({dirPaths:e.map((e=>e.dirPath))})}showPrompt(e){const{event:t,parent:n,type:i}=e;if(this.logger.log("Show prompt",{parent:n,type:i}),n.children.some((e=>e instanceof N)))return;t.preventDefault();const s=new N({parent:n,forNode:i,onConfirm:((e,t)=>{if(this.logger.log("Prompt confirm",{prompt:e,name:t}),!t)return;const n=e.parent.path,s=S.join(e.parent.path,t);this.removeFromParent(e),this.notifyOnDirsChangeLs({dirPaths:[n]}),this.notifyOnNewItemConfirmLs({fullPath:s,name:t,type:i})}).bind(this),onBlur:(e=>{this.logger.log("Prompt blur",{prompt:e});const t=e.parent.path;this.removeFromParent(e),this.notifyOnDirsChangeLs({dirPaths:[t]})}).bind(this)});n.children.push(s),this.notifyOnDirsChangeLs({dirPaths:[s.parent.path]}),this.notifyOnShowPromptLs({dirPath:s.parent.path})}serialize(e,t,n){return this.logger.log("Serialize"),[this.root.serialize(e,t,n)]}print(e=this.root,t=this.startingPrintIndent){const n=" ".repeat(t);console.log(n+e.path,`(${e.name})`);for(const i of e.children)i instanceof _?this.print(i,t+1):console.log(n+" "+i.path,`(${i.name})`)}find(e,t=this.root){if(this.logger.log("Find (recursion)",{currentPath:t.path,targetPath:e}),e=S.normalize(e),t.path===e)return t;const n=e.split(S.sep).length-1;if(!(t.level>n)&&(t instanceof L||t instanceof _))for(const n of t.children){const t=this.find(e,n);if(t)return t}}mkDir(e){this.logger.log("Make dir",e);const t=this.find(e.parentPath);if(!t)throw new Error(`Parent dir '${e.parentPath}' not found`);if(!(t instanceof L||t instanceof _))throw new Error("Parent is not a dir or root");const n=new _({parent:t,name:e.name,onAddItem:({event:e,dir:t,type:n})=>this.showPrompt({event:e,parent:t,type:n})});return t.children.push(n),n}mkAll(e){this.logger.log("Make all",e);const t=e.split(S.sep);let n,i="/";for(const e of t)if(i=S.join(i,e),!this.find(i)){const t=S.dirname(i);n=this.mkDir({parentPath:t,name:e})}return n}removeFromParent(e){const{parent:t}=e;(t instanceof L||t instanceof _)&&(t.children=t.children.filter((t=>t!==e))),e.parent=void 0}notifyOnShowPromptLs(e){this.logger.log("Notify on show prompt",e),this.onShowPromptLs.forEach((t=>t(e)))}notifyOnNewItemConfirmLs(e){this.logger.log("Notify on new item confirm",e),this.onNewItemConfirmLs.forEach((t=>t(e)))}notifyOnDirsChangeLs(e){this.logger.log("Notify on dirs change",e),this.onDirsChangeLs.forEach((t=>t(e)))}}function j(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)}!function(e){e[e.Stdout=0]="Stdout",e[e.Stderr=1]="Stderr"}(R||(R={}));class A{constructor(e,t){this.contextID=e,this.templateID=t,this.output=[],this.filesystem=new $,this.isReady=!1,this.id=`${e}_${j(t)}`,this.template=u[this.templateID]}restart(){this.output=[],this.isReady=!1,this.filesystem.setDirsContent([{dirPath:"/",content:[]}])}logOutput(e,t){this.output=[...this.output,{message:e,source:t}]}rootDir(){return this.template.root_dir}}function M(e,{environmentID:t,template:n}){const i={type:d.RunningEnvironment.Start,payload:{environmentID:t,template:n}};e.send(i)}function W(e,{environmentID:t,executionID:n,command:i}){const s={type:d.RunningEnvironment.ExecCmd,payload:{environmentID:t,executionID:n,command:i}};e.send(s)}function H(e,{environmentID:t,path:n,content:i}){const s={type:d.RunningEnvironment.WriteFile,payload:{environmentID:t,path:n,content:i}};e.send(s)}class z{constructor(e){var t,n;this.opts=e,this.fsWriteSubscribers=[],this.logger=new s(`EvaluationContext [${e.templateID}]`,e.debug),this.env=new A(this.contextID,e.templateID),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.opts.conn.sessionID&&this.handleConnectionOpen(this.opts.conn.sessionID),this.opts.conn.isClosed&&this.handleConnectionClose(),M(this.opts.conn,{environmentID:this.env.id,template:this.env.template}),null===(n=(t=this.opts).onEnvChange)||void 0===n||n.call(t,this.env)}get contextID(){return this.opts.contextID}restart(){this.logger.log("Restart",this.opts.conn.sessionID),this.env.restart(),M(this.opts.conn,{environmentID:this.env.id,template:this.env.template})}destroy(){this.logger.log("Destroy"),this.unsubscribeConnHandler(),this.env.filesystem.removeAllListeners(),this.fsWriteSubscribers=[]}getFile({path:e}){return o(this,void 0,void 0,(function*(){let t;this.logger.log("Get file",{filepath:e});const n=new Promise(((e,n)=>{t=e,setTimeout((()=>{n("Timeout")}),1e4)})),i=n=>{n.path.endsWith(e)&&t(n.content)};this.env.filesystem.addListener("onFileContent",i),function(e,{environmentID:t,path:n}){const i={type:d.RunningEnvironment.GetFile,payload:{environmentID:t,path:n}};e.send(i)}(this.opts.conn,{environmentID:this.env.id,path:e});try{return yield n}catch(t){throw new Error(`Error retrieving file ${e}: ${t}`)}finally{this.env.filesystem.removeListener("onFileContent",i)}}))}deleteFile({path:e}){this.logger.log("Delete file",{filepath:e}),function(e,{environmentID:t,path:n}){const i={type:d.RunningEnvironment.RemoveFile,payload:{environmentID:t,path:n}};e.send(i)}(this.opts.conn,{environmentID:this.env.id,path:e})}updateFile({path:e,content:t}){return o(this,void 0,void 0,(function*(){let n;this.logger.log("Update file",{filepath:e});const i=new Promise(((e,t)=>{n=e,setTimeout((()=>{t("Timeout")}),1e4)})),s=t=>{t.path.endsWith(e)&&n()};this.subscribeFSWrite(s),H(this.opts.conn,{environmentID:this.env.id,path:e,content:t});try{yield i}catch(t){throw new Error(`File ${e} not written to VM: ${t}`)}finally{this.unsubscribeFSWrite(s)}}))}createDir({path:e}){this.logger.log("Create dir",{filepath:e}),function(e,{environmentID:t,path:n}){const i={type:d.RunningEnvironment.CreateDir,payload:{environmentID:t,path:n}};e.send(i)}(this.opts.conn,{environmentID:this.env.id,path:e})}listDir({path:e}){this.logger.log("List dir",{filepath:e}),function(e,{environmentID:t,path:n}){const i={type:d.RunningEnvironment.ListDir,payload:{environmentID:t,path:n}};e.send(i)}(this.opts.conn,{environmentID:this.env.id,path:e})}executeCode({executionID:e,code:t}){this.logger.log("Execute code",{executionID:e});const n=u[this.env.templateID];if(void 0===n.toCommand)return;const i=`${e}${n.fileExtension}`,s=S.join("/src",i);H(this.opts.conn,{environmentID:this.env.id,path:s,content:t});const o=S.join(n.root_dir,s),r=n.toCommand(o);W(this.opts.conn,{environmentID:this.env.id,executionID:e,command:r})}executeCommand({executionID:e,command:t}){this.logger.log("Execute shell command",{executionID:e,command:t}),W(this.opts.conn,{environmentID:this.env.id,executionID:e,command:t})}subscribeFSWrite(e){this.fsWriteSubscribers.push(e)}unsubscribeFSWrite(e){const t=this.fsWriteSubscribers.indexOf(e);t>-1&&this.fsWriteSubscribers.splice(t,1)}handleConnectionOpen(e){var t,n;this.restart(),null===(n=(t=this.opts).onSessionChange)||void 0===n||n.call(t,{status:p.Connected,sessionID:e})}handleConnectionClose(){var e,t;null===(t=(e=this.opts).onSessionChange)||void 0===t||t.call(e,{status:p.Connecting})}handleConnectionMessage(e){switch(this.logger.log("Handling message from remote Runner",{message:e}),e.type){case d.RunningEnvironment.StartAck:{const t=e;this.vmenv_handleStartAck(t.payload);break}case d.RunningEnvironment.CmdOut:{const t=e;this.vmenv_handleCmdOut(t.payload);break}case d.RunningEnvironment.CmdExit:{const t=e;this.vmenv_handleCmdExit(t.payload);break}case d.RunningEnvironment.FSEventWrite:{const t=e;this.vmenv_handleFSEventWrite(t.payload);break}case d.RunningEnvironment.FileContent:{const t=e;this.vmenv_handleFileContent(t.payload);break}case d.RunningEnvironment.FSEventCreate:{const t=e;this.vmenv_handleFSEventCreate(t.payload);break}case d.RunningEnvironment.FSEventRemove:{const t=e;this.vmenv_handleFSEventRemove(t.payload);break}case d.RunningEnvironment.DirContent:{const t=e;this.vmenv_handleDirContent(t.payload);break}case d.RunningEnvironment.Stderr:{const t=e;this.vmenv_handleStderr(t.payload);break}case d.RunningEnvironment.Stdout:{const t=e;this.vmenv_handleStdout(t.payload);break}default:this.logger.warn("Unknown message type",{message:e})}}vmenv_handleFSEventCreate(e){this.logger.log('[vmenv] Handling "FSEventCreate"',e);const t=S.basename(e.path),n=S.dirname(e.path),i="Directory"===e.type?"Dir":"File";this.env.filesystem.addNodeToDir(n,{name:t,type:i})}vmenv_handleFSEventRemove(e){this.logger.log('[vmenv] Handling "FSEventRemove"',{payload:e});const t=S.basename(e.path),n=S.dirname(e.path);this.env.filesystem.removeNodeFromDir(n,{name:t})}vmenv_handleDirContent(e){this.logger.log('[vmenv] Handling "DirContent"',e);const t=[];for(const n of e.content){const e=S.basename(n.path),i="Directory"===n.type?"Dir":"File";t.push({name:e,type:i})}this.env.filesystem.setDirsContent([{dirPath:e.dirPath,content:t}])}vmenv_handleCmdExit(e){var t,n;this.logger.log('[vmenv] Handling "CmdExit"',e),void 0!==e.error&&(null===(n=(t=this.opts).onCmdOut)||void 0===n||n.call(t,{environmentID:e.environmentID,executionID:e.executionID,stderr:e.error}))}vmenv_handleFSEventWrite(e){this.logger.log('[vmenv] Handling "FSEventWrite"',e),this.fsWriteSubscribers.forEach((t=>t(e)))}vmenv_handleFileContent(e){this.logger.log('[vmenv] Handling "FileContent"',{environmentID:e.environmentID,path:e.path}),this.env.filesystem.setFileContent(e)}vmenv_handleStartAck(e){var t,n;this.logger.log('[vmenv] Handling "StartAck"',{payload:e}),this.env.isReady=!0,null===(n=(t=this.opts).onEnvChange)||void 0===n||n.call(t,this.env)}vmenv_handleCmdOut(e){var t,n;this.logger.log('[vmenv] Handling "CmdOut"',e),null===(n=(t=this.opts).onCmdOut)||void 0===n||n.call(t,e)}vmenv_handleStderr(e){this.logger.log('[vmenv] Handling "Stderr"',e),this.env.logOutput(e.message,R.Stderr)}vmenv_handleStdout(e){this.logger.log('[vmenv] Handling "Stdout"',e),this.env.logOutput(e.message,R.Stdout)}}class T{constructor(){this.logger=new s("Runner"),this.conn=new g,this.sessManager=new f(this.conn)}static get obj(){return T._obj||(T._obj=new T)}get session(){return this.sessManager.session}get status(){return this.sessManager.status}reset(){this.logger.log("Reset"),this.sessManager.reset()}createContext(e){return new z(Object.assign(Object.assign({},e),{conn:this.conn}))}__debug__loadNewSession(){this.logger.log("__debug__loadNewSession"),this.sessManager.reset()}}const G=(U="1234567890abcdefghijklmnopqrstuvwxyz",q=6,()=>{let e="",t=q;for(;t--;)e+=U[Math.random()*U.length|0];return e});var U,q,B;!function(e){e[e.Disconnected=0]="Disconnected",e[e.Connecting=1]="Connecting",e[e.Connected=2]="Connected"}(B||(B={}));class V{constructor(e){this.opts=e,this.contextID="default",this.executionID=G(),this._isDestroyed=!1,this._isEnvReady=!1,this._sessionStatus=p.Disconnected,this._status=B.Disconnected;const t=this.getURL.bind(this),n=()=>this.opts.env,i=()=>this.executionID,s=e=>this.isEnvReady=e,o=e=>this.sessionStatus=e,r=e=>this.sessionID=e;this.context=T.obj.createContext({debug:e.debug,templateID:e.env,contextID:this.contextID,onEnvChange(i){var o;i.templateID===n()&&(s(i.isReady),null===(o=e.onURLChange)||void 0===o||o.call(e,t))},onSessionChange({status:n,sessionID:i}){var s;r(i),o(n),null===(s=e.onURLChange)||void 0===s||s.call(e,t)},onCmdOut(t){var n,s;t.executionID===i()&&(void 0!==t.stdout&&(null===(n=e.onStdout)||void 0===n||n.call(e,t.stdout)),void 0!==t.stderr&&(null===(s=e.onStderr)||void 0===s||s.call(e,t.stderr)))}})}get sessionID(){return this._sessionID}set sessionID(e){this._sessionID=e}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)}get env(){return this.context.env}get fs(){const e=this.env.filesystem;return{delete:this.deleteFile.bind(this),listDir:this.listDir.bind(this),createDir:this.createDir.bind(this),get:this.getFile.bind(this),write:this.writeFile.bind(this),addListener:e.addListener.bind(e),removeListener:e.removeListener.bind(e),serialize:e.serialize.bind(e)}}getURL(e){if(this.status===B.Connected&&this.sessionID&&this.env.isReady)return`https://${e}-${this.env.id}-${this.sessionID}.o.usedevbook.com`}runCmd(e){if(this.status!==B.Connected)throw new Error("Not connected to the VM yet.");this.executionID=G(),this.context.executeCommand({executionID:this.executionID,command:e})}runCode(e){if(this.status!==B.Connected)throw new Error("Not connected to the VM yet.");this.executionID=G(),this.context.executeCode({executionID:this.executionID,code:e})}destroy(){this.context.destroy(),this.isDestroyed=!0}listDir(e){if(this.status!==B.Connected)throw new Error("Not connected to the VM yet.");return this.context.listDir({path:e})}createDir(e){if(this.status!==B.Connected)throw new Error("Not connected to the VM yet.");return this.context.createDir({path:e})}deleteFile(e){if(this.status!==B.Connected)throw new Error("Not connected to the VM yet.");return this.context.deleteFile({path:e})}getFile(e){if(this.status!==B.Connected)throw new Error("Not connected to the VM yet.");return this.context.getFile({path:e})}writeFile(e,t){if(this.status!==B.Connected)throw new Error("Not connected to the VM yet.");return this.context.updateFile({path:e,content:t})}updateStatus(){if(this.isDestroyed)return void(this.status!==B.Disconnected&&(this.status=B.Disconnected));let e;switch(this.sessionStatus){case p.Disconnected:e=B.Disconnected;break;case p.Connecting:e=B.Connecting;break;case p.Connected:if(!this.isEnvReady){e=B.Connecting;break}e=B.Connected}this.status=e}}function J({env:s,debug:o,port:r}){const[a,h]=e(B.Disconnected),[l,d]=e([]),[c,u]=e([]),[g,m]=e(),p=t((()=>(u([]),d([]),m(void 0),new V({debug:o,env:s,onStatusChange(e){h(e)},onStderr(e){d((t=>[...t,e]))},onStdout(e){u((t=>[...t,e]))},onURLChange(e){r&&m(e(r))}}))),[s,o,r]),v=n((e=>{u([]),d([]),p.runCmd(e)}),[p]),f=n((e=>{u([]),d([]),p.runCode(e)}),[p]);return i((function(){return()=>p.destroy()}),[p]),{stderr:l,stdout:c,runCmd:v,runCode:f,status:a,fs:p.fs,url:g}}export{V as Devbook,B as DevbookStatus,c as Env,J as useDevbook};
***************************************************************************** */function s(e,t,n,i){return new(n||(n=Promise))((function(s,o){function r(e){try{a(i.next(e))}catch(e){o(e)}}function h(e){try{a(i.throw(e))}catch(e){o(e)}}function a(e){var t;e.done?s(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(r,h)}a((i=i.apply(e,t||[])).next())}))}function o(e){return new Promise((t=>setTimeout(t,e)))}var r,h,a;!function(e){e.Error="Runner.Error"}(r||(r={})),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",e.RunCode="RunningEnvironment.Run"}(h||(h={})),function(e){e.Error="CodeCell.Error"}(a||(a={}));const l={Runner:r,RunningEnvironment:h,CodeCell:a};class d{constructor(){this.url="wss://orchestrator.usedevbook.com",this.logger=new i("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.sessionID),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(e){var t;this.logger.log("Connection opened",{readyState:null===(t=this.client)||void 0===t?void 0:t.readyState}),this.handlers.forEach((t=>t.onOpen(e)))}_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 o(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 c,u;!function(e){e.Ok="Ok",e.Terminated="Terminated"}(c||(c={}));class g{constructor(e,t=new Date){this.id=e,this.lastPing=t,this.logger=new i("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===c.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"}(u||(u={}));class m{constructor(e){this.conn=e,this.logger=new i("SessionManager"),this.url="https://orchestrator.usedevbook.com",this.isGettingSessionActive=!1,this.status=u.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=u.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=u.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),i=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,i),yield o(3e3);continue}for(this.session=new g(i.sessionID),this.logger.log(`Acquired session "${this.session.id}"`),this.cachedSessionID=this.session.id,this.status=u.Connected,this.conn.connect(this.session.id),this.logger.log(`Started pinging session "${this.session.id}"`);this.session;)try{yield this.session.ping(),yield o(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=u.Disconnected,this.conn.close()}catch(e){this.logger.error("Failed to acquire Runner session. Will try again in 3s",e),yield o(3e3)}}}))}}function p(e,t){for(var n=0,i=e.length-1;i>=0;i--){var s=e[i];"."===s?e.splice(i,1):".."===s?(e.splice(i,1),n++):n&&(e.splice(i,1),n--)}if(t)for(;n--;n)e.unshift("..");return e}var v=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/,f=function(e){return v.exec(e).slice(1)};function y(){for(var e="",t=!1,n=arguments.length-1;n>=-1&&!t;n--){var i=n>=0?arguments[n]:"/";if("string"!=typeof i)throw new TypeError("Arguments to path.resolve must be strings");i&&(e=i+"/"+e,t="/"===i.charAt(0))}return(t?"/":"")+(e=p(S(e.split("/"),(function(e){return!!e})),!t).join("/"))||"."}function D(e){var t=C(e),n="/"===E(e,-1);return(e=p(S(e.split("/"),(function(e){return!!e})),!t).join("/"))||t||(e="."),e&&n&&(e+="/"),(t?"/":"")+e}function C(e){return"/"===e.charAt(0)}var w={extname:function(e){return f(e)[3]},basename:function(e,t){var n=f(e)[2];return t&&n.substr(-1*t.length)===t&&(n=n.substr(0,n.length-t.length)),n},dirname:function(e){var t=f(e),n=t[0],i=t[1];return n||i?(i&&(i=i.substr(0,i.length-1)),n+i):"."},sep:"/",delimiter:":",relative:function(e,t){function n(e){for(var t=0;t<e.length&&""===e[t];t++);for(var n=e.length-1;n>=0&&""===e[n];n--);return t>n?[]:e.slice(t,n-t+1)}e=y(e).substr(1),t=y(t).substr(1);for(var i=n(e.split("/")),s=n(t.split("/")),o=Math.min(i.length,s.length),r=o,h=0;h<o;h++)if(i[h]!==s[h]){r=h;break}var a=[];for(h=r;h<i.length;h++)a.push("..");return(a=a.concat(s.slice(r))).join("/")},join:function(){var e=Array.prototype.slice.call(arguments,0);return D(S(e,(function(e,t){if("string"!=typeof e)throw new TypeError("Arguments to path.join must be strings");return e})).join("/"))},isAbsolute:C,normalize:D,resolve:y};function S(e,t){if(e.filter)return e.filter(t);for(var n=[],i=0;i<e.length;i++)t(e[i],i,e)&&n.push(e[i]);return n}var b,E="b"==="ab".substr(-1)?function(e,t,n){return e.substr(t,n)}:function(e,t,n){return t<0&&(t=e.length+t),e.substr(t,n)};class I{get level(){return w.normalize(this.path).split(w.sep).length-1}}function R(e){return e.sort(((e,t)=>"Prompt"===e.type?-2:e.type!==t.type?"Dir"===e.type?-1:"Dir"===t.type?1:0:e.key.localeCompare(t.key))),e}class F extends I{constructor({name:e,parent:t,onAddItem:n}){super(),this.children=[],this.name=e,this.parent=t,this.addItemHandler=n,this.path=w.join(this.parent.path,this.name)}removeChildNode(e){this.children=this.children.filter((t=>t!==e))}serialize(e,t,n){const i=this.children.map((i=>i.serialize(e,t,n)));return{type:"Dir",key:this.path,title:e({name:this.name,onAddFileMouseDown:e=>{this.addItemHandler({event:e,dir:this,type:"File"})},onAddDirMouseDown:e=>{this.addItemHandler({event:e,dir:this,type:"Dir"})}}),children:R(i)}}}class k extends I{constructor({name:e,parent:t}){super(),this.name=e,this.parent=t,this.path=w.join(this.parent.path,this.name)}serialize(){return{type:"File",key:this.path,title:this.name,isLeaf:!0}}}class P extends I{constructor({parent:e,forNode:t,onConfirm:n,onBlur:i}){super(),this.name="name-prompt",this.parent=e,this.forNode=t,this.path=w.join(e.path,this.name),this.onConfirm=n,this.onBlur=i}serialize(e,t,n){return{type:"Prompt",key:this.path,title:t({onConfirm:e=>{var t;return null===(t=this.onConfirm)||void 0===t?void 0:t.call(this,this,e)},onBlur:()=>{var e;return null===(e=this.onBlur)||void 0===e?void 0:e.call(this,this)}}),isLeaf:!0,selectable:!1,icon:n({type:this.forNode})}}}class x extends I{constructor({onAddItem:e}){super(),this.name="/",this.path="/",this.parent=void 0,this.children=[],this.addItemHandler=e}serialize(e,t,n){const i=this.children.map((i=>i.serialize(e,t,n)));return{type:"Root",key:this.path,title:e({name:this.name,onAddFileMouseDown:e=>{this.addItemHandler({event:e,dir:this,type:"File"})},onAddDirMouseDown:e=>{this.addItemHandler({event:e,dir:this,type:"Dir"})}}),children:R(i)}}}class L extends I{constructor({parent:e}){super(),this.name="empty-node",this.parent=e,this.path=w.join(this.parent.path,this.name)}serialize(){return{type:"Empty",key:this.path,title:"Empty Directory",isLeaf:!0,disabled:!0}}}class O{constructor(){this.logger=new i("Filesystem"),this.root=new x({onAddItem:({event:e,dir:t,type:n})=>this.showPrompt({event:e,parent:t,type:n})}),this.startingPrintIndent=0,this.onNewItemConfirmLs=[],this.onDirsChangeLs=[],this.onFileContentLs=[],this.onShowPromptLs=[]}removeAllListeners(){this.onNewItemConfirmLs=[],this.onDirsChangeLs=[],this.onFileContentLs=[],this.onShowPromptLs=[]}addListener(e,t){switch(e){case"onNewItemConfirm":this.onNewItemConfirmLs.push(t);break;case"onDirsChange":this.onDirsChangeLs.push(t);break;case"onFileContent":this.onFileContentLs.push(t);break;case"onShowPrompt":this.onShowPromptLs.push(t);break;default:throw new Error(`Unknown event type: ${e}`)}}removeListener(e,t){switch(e){case"onNewItemConfirm":this.onNewItemConfirmLs=this.onNewItemConfirmLs.filter((e=>e!==t));break;case"onDirsChange":this.onDirsChangeLs=this.onDirsChangeLs.filter((e=>e!==t));break;case"onFileContent":this.onFileContentLs=this.onFileContentLs.filter((e=>e!==t));break;case"onShowPrompt":this.onShowPromptLs=this.onShowPromptLs.filter((e=>e!==t));break;default:throw new Error(`Unknown event type: ${e}`)}}addNodeToDir(e,t){this.logger.log("Adding node to dir",{dirPath:e,node:t});let n=this.find(e);if(n||(this.logger.log("Dir not found, will make all",{dirPath:e}),n=this.mkAll(e)),!n)throw new Error("dirNode is undefined");if(!(n instanceof x||n instanceof F))throw new Error(`Node at '${e}' is not a directory or a root node`);if(n.children.some((e=>e.name===t.name)))return;let i;i="Dir"===t.type?new F({name:t.name,parent:n,onAddItem:({event:e,dir:t,type:n})=>this.showPrompt({event:e,parent:t,type:n})}):new k({name:t.name,parent:n}),1===n.children.length&&n.children[0]instanceof L?n.children=[i]:n.children.push(i),this.notifyOnDirsChangeLs({dirPaths:[e]})}removeNodeFromDir(e,t){this.logger.log("Remove node from dir",{dirPath:e,nodeName:t.name});const n=this.find(e);if(!n)throw new Error(`No node with path '${e}'`);if(!(n instanceof x||n instanceof F))throw new Error(`Node at '${e}' is not a directory or root node`);const i=n.children.length;n.children=n.children.filter((e=>e.name!==t.name));i!==n.children.length?(0===n.children.length&&(n.children=[new L({parent:n})]),this.notifyOnDirsChangeLs({dirPaths:[e]})):this.logger.warn("Node not found in dir",{dirPath:e,nodeName:t.name})}setFileContent(e){this.logger.log("Update file content",e),this.onFileContentLs.forEach((t=>t(e)))}setDirsContent(e){this.logger.log("Set dirs content",e);for(const t of e){let e=this.find(t.dirPath);if(e||(this.logger.log("Dir not found, will make all",{dirPath:t.dirPath}),e=this.mkAll(t.dirPath)),!e)throw new Error("dirNode is undefined");if(!(e instanceof x||e instanceof F))throw new Error(`Node at '${t.dirPath}' is not a directory or a root node`);const n=e.children.find((e=>e instanceof P));if(t.content.length){const n=[];for(const i of t.content){let t;t="Dir"===i.type?new F({name:i.name,parent:e,onAddItem:({event:e,dir:t,type:n})=>this.showPrompt({event:e,parent:t,type:n})}):new k({name:i.name,parent:e}),n.push(t)}e.children=n}else e.children=[new L({parent:e})];n&&e.children.push(n)}this.notifyOnDirsChangeLs({dirPaths:e.map((e=>e.dirPath))})}showPrompt(e){const{event:t,parent:n,type:i}=e;if(this.logger.log("Show prompt",{parent:n,type:i}),n.children.some((e=>e instanceof P)))return;t.preventDefault();const s=new P({parent:n,forNode:i,onConfirm:((e,t)=>{if(this.logger.log("Prompt confirm",{prompt:e,name:t}),!t)return;const n=e.parent.path,s=w.join(e.parent.path,t);this.removeFromParent(e),this.notifyOnDirsChangeLs({dirPaths:[n]}),this.notifyOnNewItemConfirmLs({fullPath:s,name:t,type:i})}).bind(this),onBlur:(e=>{this.logger.log("Prompt blur",{prompt:e});const t=e.parent.path;this.removeFromParent(e),this.notifyOnDirsChangeLs({dirPaths:[t]})}).bind(this)});n.children.push(s),this.notifyOnDirsChangeLs({dirPaths:[s.parent.path]}),this.notifyOnShowPromptLs({dirPath:s.parent.path})}serialize(e,t,n){return this.logger.log("Serialize"),[this.root.serialize(e,t,n)]}print(e=this.root,t=this.startingPrintIndent){const n=" ".repeat(t);console.log(n+e.path,`(${e.name})`);for(const i of e.children)i instanceof F?this.print(i,t+1):console.log(n+" "+i.path,`(${i.name})`)}find(e,t=this.root){if(this.logger.log("Find (recursion)",{currentPath:t.path,targetPath:e}),e=w.normalize(e),t.path===e)return t;const n=e.split(w.sep).length-1;if(!(t.level>n)&&(t instanceof x||t instanceof F))for(const n of t.children){const t=this.find(e,n);if(t)return t}}mkDir(e){this.logger.log("Make dir",e);const t=this.find(e.parentPath);if(!t)throw new Error(`Parent dir '${e.parentPath}' not found`);if(!(t instanceof x||t instanceof F))throw new Error("Parent is not a dir or root");const n=new F({parent:t,name:e.name,onAddItem:({event:e,dir:t,type:n})=>this.showPrompt({event:e,parent:t,type:n})});return t.children.push(n),n}mkAll(e){this.logger.log("Make all",e);const t=e.split(w.sep);let n,i="/";for(const e of t)if(i=w.join(i,e),!this.find(i)){const t=w.dirname(i);n=this.mkDir({parentPath:t,name:e})}return n}removeFromParent(e){const{parent:t}=e;(t instanceof x||t instanceof F)&&(t.children=t.children.filter((t=>t!==e))),e.parent=void 0}notifyOnShowPromptLs(e){this.logger.log("Notify on show prompt",e),this.onShowPromptLs.forEach((t=>t(e)))}notifyOnNewItemConfirmLs(e){this.logger.log("Notify on new item confirm",e),this.onNewItemConfirmLs.forEach((t=>t(e)))}notifyOnDirsChangeLs(e){this.logger.log("Notify on dirs change",e),this.onDirsChangeLs.forEach((t=>t(e)))}}function _(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)}!function(e){e[e.Stdout=0]="Stdout",e[e.Stderr=1]="Stderr"}(b||(b={}));class N{constructor(e,t){this.contextID=e,this.templateID=t,this.output=[],this.filesystem=new O,this.isReady=!1,this.id=`${e}_${_(t)}`}restart(){this.output=[],this.isReady=!1,this.filesystem.setDirsContent([{dirPath:"/",content:[]}])}logOutput(e,t){this.output=[...this.output,{message:e,source:t}]}}function $(e,{environmentID:t,templateID:n}){const i={type:l.RunningEnvironment.Start,payload:{environmentID:t,templateID:n}};e.send(i)}class A{constructor(e){var t,n;this.opts=e,this.fsWriteSubscribers=[],this.fileContentSubscribers=[],this.logger=new i(`EvaluationContext [${e.templateID}]`,e.debug),this.env=new N(this.contextID,e.templateID);this.unsubscribeConnHandler=this.opts.conn.subscribeHandler({onOpen:e=>this.handleConnectionOpen(e),onMessage:e=>this.handleConnectionMessage(e),onClose:()=>this.handleConnectionClose()}),this.opts.conn.isOpen&&this.opts.conn.sessionID&&this.handleConnectionOpen(this.opts.conn.sessionID),this.opts.conn.isClosed&&this.handleConnectionClose(),$(this.opts.conn,{environmentID:this.env.id,templateID:this.env.templateID}),null===(n=(t=this.opts).onEnvChange)||void 0===n||n.call(t,this.env)}get contextID(){return this.opts.contextID}restart(){this.logger.log("Restart",this.opts.conn.sessionID),this.env.restart(),$(this.opts.conn,{environmentID:this.env.id,templateID:this.env.templateID})}destroy(){this.logger.log("Destroy"),this.unsubscribeConnHandler(),this.fsWriteSubscribers=[],this.fileContentSubscribers=[]}getFile({path:e}){return s(this,void 0,void 0,(function*(){let t;this.logger.log("Get file",{filepath:e});const n=new Promise(((e,n)=>{t=e,setTimeout((()=>{n("Timeout")}),1e4)})),i=n=>{n.path.endsWith(e)&&t(n.content)};this.subscribeFileContent(i),function(e,{environmentID:t,path:n}){const i={type:l.RunningEnvironment.GetFile,payload:{environmentID:t,path:n}};e.send(i)}(this.opts.conn,{environmentID:this.env.id,path:e});try{return yield n}catch(t){throw new Error(`Error retrieving file ${e}: ${t}`)}finally{this.unsubscribeFileContent(i)}}))}deleteFile({path:e}){this.logger.log("Delete file",{filepath:e}),function(e,{environmentID:t,path:n}){const i={type:l.RunningEnvironment.RemoveFile,payload:{environmentID:t,path:n}};e.send(i)}(this.opts.conn,{environmentID:this.env.id,path:e})}updateFile({path:e,content:t}){return s(this,void 0,void 0,(function*(){let n;this.logger.log("Update file",{filepath:e});const i=new Promise(((e,t)=>{n=e,setTimeout((()=>{t("Timeout")}),1e4)})),s=t=>{t.path.endsWith(e)&&n()};this.subscribeFSWrite(s),function(e,{environmentID:t,path:n,content:i}){const s={type:l.RunningEnvironment.WriteFile,payload:{environmentID:t,path:n,content:i}};e.send(s)}(this.opts.conn,{environmentID:this.env.id,path:e,content:t});try{yield i}catch(t){throw new Error(`File ${e} not written to VM: ${t}`)}finally{this.unsubscribeFSWrite(s)}}))}createDir({path:e}){this.logger.log("Create dir",{filepath:e}),function(e,{environmentID:t,path:n}){const i={type:l.RunningEnvironment.CreateDir,payload:{environmentID:t,path:n}};e.send(i)}(this.opts.conn,{environmentID:this.env.id,path:e})}listDir({path:e}){this.logger.log("List dir",{filepath:e}),function(e,{environmentID:t,path:n}){const i={type:l.RunningEnvironment.ListDir,payload:{environmentID:t,path:n}};e.send(i)}(this.opts.conn,{environmentID:this.env.id,path:e})}executeCommand({executionID:e,command:t}){this.logger.log("Execute shell command",{executionID:e,command:t}),function(e,{environmentID:t,executionID:n,command:i}){const s={type:l.RunningEnvironment.ExecCmd,payload:{environmentID:t,executionID:n,command:i}};e.send(s)}(this.opts.conn,{environmentID:this.env.id,executionID:e,command:t})}subscribeFileContent(e){this.fileContentSubscribers.push(e)}unsubscribeFileContent(e){const t=this.fileContentSubscribers.indexOf(e);t>-1&&this.fileContentSubscribers.splice(t,1)}subscribeFSWrite(e){this.fsWriteSubscribers.push(e)}unsubscribeFSWrite(e){const t=this.fsWriteSubscribers.indexOf(e);t>-1&&this.fsWriteSubscribers.splice(t,1)}handleConnectionOpen(e){var t,n;this.restart(),null===(n=(t=this.opts).onSessionChange)||void 0===n||n.call(t,{status:u.Connected,sessionID:e})}handleConnectionClose(){var e,t;null===(t=(e=this.opts).onSessionChange)||void 0===t||t.call(e,{status:u.Connecting})}handleConnectionMessage(e){switch(this.logger.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}case l.RunningEnvironment.CmdExit:{const t=e;this.vmenv_handleCmdExit(t.payload);break}case l.RunningEnvironment.FSEventWrite:{const t=e;this.vmenv_handleFSEventWrite(t.payload);break}case l.RunningEnvironment.FileContent:{const t=e;this.vmenv_handleFileContent(t.payload);break}case l.RunningEnvironment.FSEventCreate:{const t=e;this.vmenv_handleFSEventCreate(t.payload);break}case l.RunningEnvironment.FSEventRemove:{const t=e;this.vmenv_handleFSEventRemove(t.payload);break}case l.RunningEnvironment.DirContent:{const t=e;this.vmenv_handleDirContent(t.payload);break}case l.RunningEnvironment.Stderr:{const t=e;this.vmenv_handleStderr(t.payload);break}case l.RunningEnvironment.Stdout:{const t=e;this.vmenv_handleStdout(t.payload);break}default:this.logger.warn("Unknown message type",{message:e})}}vmenv_handleFSEventCreate(e){this.logger.log('[vmenv] Handling "FSEventCreate"',e);const t=w.basename(e.path),n=w.dirname(e.path),i="Directory"===e.type?"Dir":"File";this.env.filesystem.addNodeToDir(n,{name:t,type:i})}vmenv_handleFSEventRemove(e){this.logger.log('[vmenv] Handling "FSEventRemove"',{payload:e});const t=w.basename(e.path),n=w.dirname(e.path);this.env.filesystem.removeNodeFromDir(n,{name:t})}vmenv_handleDirContent(e){this.logger.log('[vmenv] Handling "DirContent"',e);const t=[];for(const n of e.content){const e=w.basename(n.path),i="Directory"===n.type?"Dir":"File";t.push({name:e,type:i})}this.env.filesystem.setDirsContent([{dirPath:e.dirPath,content:t}])}vmenv_handleCmdExit(e){var t,n;this.logger.log('[vmenv] Handling "CmdExit"',e),void 0!==e.error&&(null===(n=(t=this.opts).onCmdOut)||void 0===n||n.call(t,{environmentID:e.environmentID,executionID:e.executionID,stderr:e.error}))}vmenv_handleFSEventWrite(e){this.logger.log('[vmenv] Handling "FSEventWrite"',e),this.fsWriteSubscribers.forEach((t=>t(e)))}vmenv_handleFileContent(e){this.logger.log('[vmenv] Handling "FileContent"',{environmentID:e.environmentID,path:e.path}),this.fileContentSubscribers.forEach((t=>t(e)))}vmenv_handleStartAck(e){var t,n;this.logger.log('[vmenv] Handling "StartAck"',{payload:e}),this.env.isReady=!0,null===(n=(t=this.opts).onEnvChange)||void 0===n||n.call(t,this.env)}vmenv_handleCmdOut(e){var t,n;this.logger.log('[vmenv] Handling "CmdOut"',e),null===(n=(t=this.opts).onCmdOut)||void 0===n||n.call(t,e)}vmenv_handleStderr(e){this.logger.log('[vmenv] Handling "Stderr"',e),this.env.logOutput(e.message,b.Stderr)}vmenv_handleStdout(e){this.logger.log('[vmenv] Handling "Stdout"',e),this.env.logOutput(e.message,b.Stdout)}}class M{constructor(){this.logger=new i("Runner"),this.conn=new d,this.sessManager=new m(this.conn)}static get obj(){return M._obj||(M._obj=new M)}get session(){return this.sessManager.session}get status(){return this.sessManager.status}reset(){this.logger.log("Reset"),this.sessManager.reset()}createContext(e){return new A(Object.assign(Object.assign({},e),{conn:this.conn}))}__debug__loadNewSession(){this.logger.log("__debug__loadNewSession"),this.sessManager.reset()}}const W=(j="1234567890abcdefghijklmnopqrstuvwxyz",H=6,()=>{let e="",t=H;for(;t--;)e+=j[Math.random()*j.length|0];return e});var j,H,z;!function(e){e.Disconnected="Disconnected",e.Connecting="Connecting",e.Connected="Connected"}(z||(z={}));class T{constructor(e){this.opts=e,this.contextID="default",this.executionID=W(),this._isDestroyed=!1,this._isEnvReady=!1,this._sessionStatus=u.Disconnected,this._status=z.Disconnected;const t=this.getURL.bind(this),n=()=>this.opts.env,i=()=>this.executionID,s=e=>this.isEnvReady=e,o=e=>this.sessionStatus=e,r=e=>this.sessionID=e;this.context=M.obj.createContext({debug:e.debug,templateID:e.env,contextID:this.contextID,onEnvChange(i){var o;i.templateID===n()&&(s(i.isReady),null===(o=e.onURLChange)||void 0===o||o.call(e,t))},onSessionChange({status:n,sessionID:i}){var s;r(i),o(n),null===(s=e.onURLChange)||void 0===s||s.call(e,t)},onCmdOut(t){var n,s;t.executionID===i()&&(void 0!==t.stdout&&(null===(n=e.onStdout)||void 0===n||n.call(e,t.stdout)),void 0!==t.stderr&&(null===(s=e.onStderr)||void 0===s||s.call(e,t.stderr)))}})}get sessionID(){return this._sessionID}set sessionID(e){this._sessionID=e}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)}get env(){return this.context.env}get fs(){const e=this.env.filesystem;return{delete:this.deleteFile.bind(this),listDir:this.listDir.bind(this),createDir:this.createDir.bind(this),get:this.getFile.bind(this),write:this.writeFile.bind(this),addListener:e.addListener.bind(e),removeListener:e.removeListener.bind(e),serialize:e.serialize.bind(e)}}getURL(e){if(this.status===z.Connected&&this.sessionID&&this.env.isReady)return`https://${e}-${this.env.id}-${this.sessionID}.o.usedevbook.com`}runCmd(e){if(this.status!==z.Connected)throw new Error("Not connected to the VM yet.");this.executionID=W(),this.context.executeCommand({executionID:this.executionID,command:e})}destroy(){this.context.destroy(),this.isDestroyed=!0}listDir(e){if(this.status!==z.Connected)throw new Error("Not connected to the VM yet.");return this.context.listDir({path:e})}createDir(e){if(this.status!==z.Connected)throw new Error("Not connected to the VM yet.");return this.context.createDir({path:e})}deleteFile(e){if(this.status!==z.Connected)throw new Error("Not connected to the VM yet.");return this.context.deleteFile({path:e})}getFile(e){if(this.status!==z.Connected)throw new Error("Not connected to the VM yet.");return this.context.getFile({path:e})}writeFile(e,t){if(this.status!==z.Connected)throw new Error("Not connected to the VM yet.");return this.context.updateFile({path:e,content:t})}updateStatus(){if(this.isDestroyed)return void(this.status!==z.Disconnected&&(this.status=z.Disconnected));let e;switch(this.sessionStatus){case u.Disconnected:e=z.Disconnected;break;case u.Connecting:e=z.Connecting;break;case u.Connected:if(!this.isEnvReady){e=z.Connecting;break}e=z.Connected}this.status=e}}function G({env:i,debug:s,port:o}){const[r,h]=e(),[a,l]=e(z.Disconnected),[d,c]=e([]),[u,g]=e([]),[m,p]=e(),v=t((e=>{r&&(g([]),c([]),r.runCmd(e))}),[r]);return n((function(){const e=new T({debug:s,env:i,onStatusChange(e){l(e)},onStderr(e){c((t=>[...t,e]))},onStdout(e){g((t=>[...t,e]))},onURLChange(e){o&&p(e(o))}});return g([]),c([]),p(void 0),h(e),()=>{e.destroy()}}),[i,s,o]),{stderr:d,stdout:u,runCmd:v,status:a,fs:null==r?void 0:r.fs,url:m}}export{T as Devbook,z as DevbookStatus,G as useDevbook};
//# sourceMappingURL=index.js.map

@@ -9,3 +9,3 @@ import { DevbookStatus, Env, FS } from '../core';

*
* This affects which runtime (NodeJS, etc.,...) will be available and used in the {@link State.runCode} function.
* This affects which runtime (NodeJS, etc.,...) will be available and used in the {@link State.runCmd} function.
*

@@ -30,11 +30,11 @@ * {@link useDevbook} hooks with different environments are isolated - each has their own filesystem and process namespace.

/**
* Stderr from the last code or command run with {@link State.runCode} or {@link State.runCmd}.
* Stderr from the last command run with {@link State.runCmd}.
*
* This array is reset when you call {@link State.runCode} or {@link State.runCmd}.
* This array is reset when you call {@link State.runCmd}.
*/
stderr: string[];
/**
* Stdout from the last code or command run with {@link State.runCode} or {@link State.runCmd}.
* Stdout from the command run with {@link State.runCmd}.
*
* This array is reset when you call {@link State.runCode} or {@link State.runCmd}.
* This array is reset when you call {@link State.runCmd}.
*/

@@ -47,10 +47,2 @@ stdout: string[];

/**
* Run `code` in the VM using the runtime you passed to this {@link useDevbook} hook as the `env`({@link Env}) parameter.
*
* This Devbook's VM shares filesystem and process namespace with other Devbooks that were created by passing the same `env`({@link Env}) to the {@link useDevbook} hooks.
*
* @param code Code to run
*/
runCode: (code: string) => void;
/**
* Run `command` in the VM.

@@ -66,3 +58,3 @@ *

*/
fs: FS;
fs?: FS;
/**

@@ -77,3 +69,3 @@ * URL address that allows you to connect to a port ({@link Opts.port})

*
* This hook exposes functions for running code ({@link State.runCode}) and commands ({@link State.runCmd}) while managing
* This hook exposes functions for running commands ({@link State.runCmd}) while managing
* {@link State.stderr}, {@link State.stdout}, and {@link State.status} - reloading the component when these fields change.

@@ -80,0 +72,0 @@ */

@@ -6,2 +6,3 @@ import { TCodeCell, BaseMessage } from './BaseMessage';

environmentID: string;
codeCellID: string;
};

@@ -8,0 +9,0 @@ }

@@ -22,3 +22,10 @@ import { CodeCell } from '../CodeCell';

environmentID: string;
template: TemplateConfig;
/**
* Either the `template` or the `templateID` field must be present.
*/
template?: TemplateConfig;
/**
* Either the `template` or the `templateID` field must be present.
*/
templateID?: string;
};

@@ -33,3 +40,3 @@ }

environmentID: string;
template: TemplateConfig;
template: Pick<TemplateConfig, 'id' | 'image'>;
/**

@@ -138,13 +145,2 @@ * A boolean indicating whether the environment has already existed or a new one was created.

/**
* Sent to remote Runner when a client requests to overwrite content of a file in the environment's filesystem.
*/
export interface RunningEnvironment_WriteFile extends BaseRunningEnvironment {
type: TRunningEnvironment.WriteFile;
payload: {
environmentID: string;
path: string;
content: string;
};
}
/**
* Sent to remote Runner when a client requests the content of a file in the environment's filesystem.

@@ -151,0 +147,0 @@ */

import * as runner from './runner';
import { templates, Env } from './template';
export { runner, templates, Env, };
export { runner, };

@@ -1,4 +0,7 @@

import { Env } from './constants';
import { Filesystem } from './runningEnvironment/filesystem';
/**
* Runtime environment to use with the Devbooks' VMs.
*/
export declare type Env = string;
/**
* Methods for accessing and manipulating this `Devbook`'s VM's filesystem.

@@ -40,11 +43,11 @@ */

*/
Disconnected = 0,
Disconnected = "Disconnected",
/**
* Devbook is trying to start or connect to a VM.
*/
Connecting = 1,
Connecting = "Connecting",
/**
* Devbook is connected to a VM and ready to run code or a command.
*/
Connected = 2
Connected = "Connected"
}

@@ -89,3 +92,3 @@ /**

*
* This affects which runtime (NodeJS, etc...) will be available and used in the {@link Devbook.runCode} function.
* This affects which runtime (NodeJS, etc...) will be available and used in the {@link Devbook.runCmd} function.
*

@@ -96,7 +99,7 @@ * `Devbook` instances with different environments are isolated - each has their own filesystem and process namespace.

/**
* This function will be called when this `Devbook` receives new stdout after you called {@link Devbook.runCode} or {@link Devbook.runCode}.
* This function will be called when this `Devbook` receives new stdout after you called {@link Devbook.runCmd}.
*/
onStdout?: (stdout: string) => void;
/**
* This function will be called when this `Devbook` receives new stderr after you called {@link Devbook.runCode} or {@link Devbook.runCode}.
* This function will be called when this `Devbook` receives new stderr after you called {@link Devbook.runCmd}.
*/

@@ -136,10 +139,2 @@ onStderr?: (stderr: string) => void;

/**
* Run `code` in the VM using the runtime you passed to this `Devbook`'s constructor as the `env`({@link Env}) parameter.
*
* This {@link Devboook}'s VM shares filesystem and process namespace with other `Devbook`'s with the same `env`({@link Env}) passed to their constructors.
*
* @param code Code to run
*/
runCode(code: string): void;
/**
* Disconnect this `Devbook` from the VM.

@@ -146,0 +141,0 @@ */

import * as rws from '../common-ts/RunnerWebSocket';
import { WebSocketConnection } from './webSocketConnection';
import { Env } from './constants';
import { RunningEnvironment } from './runningEnvironment';
import { SessionStatus } from './session/sessionManager';
import { Env } from './devbook';
export interface EvaluationContextOpts {

@@ -23,2 +23,3 @@ contextID: string;

private fsWriteSubscribers;
private fileContentSubscribers;
readonly env: RunningEnvironment;

@@ -49,6 +50,2 @@ private readonly unsubscribeConnHandler;

}): void;
executeCode({ executionID, code }: {
executionID: string;
code: string;
}): void;
executeCommand({ executionID, command }: {

@@ -58,2 +55,4 @@ executionID: string;

}): void;
private subscribeFileContent;
private unsubscribeFileContent;
private subscribeFSWrite;

@@ -60,0 +59,0 @@ private unsubscribeFSWrite;

@@ -1,3 +0,2 @@

export type { FS } from './devbook';
export type { FS, Env, } from './devbook';
export { default as Devbook, DevbookStatus, } from './devbook';
export { Env } from './constants';

@@ -1,4 +0,3 @@

import { TemplateConfig } from '../../common-ts/TemplateConfig';
import { Env } from '../constants';
import * as envfs from './filesystem';
import { Env } from '../devbook';
export declare enum OutputSource {

@@ -16,3 +15,2 @@ Stdout = 0,

readonly id: string;
readonly template: TemplateConfig;
output: OutputEntry[];

@@ -24,4 +22,3 @@ readonly filesystem: envfs.Filesystem;

logOutput(message: string, source: OutputSource): void;
rootDir(): string;
}
export default RunningEnvironment;

@@ -1,2 +0,2 @@

import { TemplateConfig } from '../../common-ts/TemplateConfig';
import { Env } from '../devbook';
import { WebSocketConnection } from '../webSocketConnection';

@@ -25,5 +25,5 @@ /**

}): void;
declare function start(conn: WebSocketConnection, { environmentID, template, }: {
declare function start(conn: WebSocketConnection, { environmentID, templateID, }: {
environmentID: string;
template: TemplateConfig;
templateID: Env;
}): void;

@@ -30,0 +30,0 @@ declare function execCmd(conn: WebSocketConnection, { environmentID, executionID, command, }: {

export { useDevbook } from './react';
export { Devbook, Env, DevbookStatus, } from './core';
export { Devbook, DevbookStatus, } from './core';

@@ -15,3 +15,3 @@ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self)["@devbookhq/sdk"]={},e.react)}(this,(function(e,t){"use strict";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(`[${this.id()}]`,...e)}warn(...e){this.isEnabled&&console.warn(`[${this.id()}]`,...e)}error(...e){console.error(`[${this.id()} ERROR]`,...e)}}

PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */function i(e,t,n,i){return new(n||(n=Promise))((function(s,o){function r(e){try{h(i.next(e))}catch(e){o(e)}}function a(e){try{h(i.throw(e))}catch(e){o(e)}}function h(e){var t;e.done?s(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(r,a)}h((i=i.apply(e,t||[])).next())}))}function s(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",e.RunCode="RunningEnvironment.Run"}(r||(r={})),function(e){e.Error="CodeCell.Error"}(a||(a={}));const h={Runner:o,RunningEnvironment:r,CodeCell:a},l="orchestrator.usedevbook.com",d="dbk_sdk_session_id",c=3e3;var u;e.Env=void 0,(u=e.Env||(e.Env={})).NextJS="nextjs-v11-components",u.NodeJS="nodejs-v16",u.Supabase="supabase",u.BananaNode="banana-node",u.BananaPython="banana-python";const g={[e.Env.NodeJS]:{id:"nodejs-v16",fileExtension:".js",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.Env.Supabase]:{id:"supabase",fileExtension:".js",image:"us-central1-docker.pkg.dev/devbookhq/devbook-runner-templates/supabase",root_dir:"/home/runner",code_cells_dir:"/home/runner/src",toCommand:e=>`node "${e}"`},[e.Env.NextJS]:{id:"nextjs-v11-components",fileExtension:".tsx",image:"us-central1-docker.pkg.dev/devbookhq/devbook-runner-templates/nextjs-v11-components",root_dir:"/home/runner",code_cells_dir:"/home/runner/src"},[e.Env.BananaNode]:{id:"banana-node",fileExtension:".js",image:"us-central1-docker.pkg.dev/devbookhq/devbook-runner-templates/banana-node",root_dir:"/home/runner",code_cells_dir:"/home/runner/src"},[e.Env.BananaPython]:{id:"banana-python",fileExtension:".py",image:"us-central1-docker.pkg.dev/devbookhq/devbook-runner-templates/banana-python",root_dir:"/home/runner",code_cells_dir:"/home/runner"}};class m{constructor(){this.url=`wss://${l}`,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.sessionID),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(e){var t;this.logger.log("Connection opened",{readyState:null===(t=this.client)||void 0===t?void 0:t.readyState}),this.handlers.forEach((t=>t.onOpen(e)))}_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 i(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 s(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(h.RunningEnvironment).includes(n.type)||Object.values(h.Runner).includes(n.type)||Object.values(h.CodeCell).includes(n.type)?n.type!==h.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 v,p;!function(e){e.Ok="Ok",e.Terminated="Terminated"}(v||(v={}));class f{constructor(e,t=new Date){this.id=e,this.lastPing=t,this.logger=new n("RunnerSession"),this.url=`https://${l}`}ping(){return i(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===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"}(p||(p={}));class D{constructor(e){this.conn=e,this.logger=new n("SessionManager"),this.url=`https://${l}`,this.isGettingSessionActive=!1,this.status=p.Disconnected,this.logger.log("Initialize"),this.getSession()}get cachedSessionID(){return sessionStorage.getItem(d)}set cachedSessionID(e){null===e?(this.logger.log("Cleared last sessionID"),sessionStorage.removeItem(d)):(this.logger.log(`Saved sessionID "${e}" as last sessionID`),sessionStorage.setItem(d,e))}reset(){this.logger.log("Reset"),this.status=p.Disconnected,this.cachedSessionID=null,this.conn.close(),this.session=void 0}getSession(){var e;return i(this,void 0,void 0,(function*(){if(!this.isGettingSessionActive)for(this.isGettingSessionActive=!0;;){this.status=p.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),i=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,i),yield s(c);continue}for(this.session=new f(i.sessionID),this.logger.log(`Acquired session "${this.session.id}"`),this.cachedSessionID=this.session.id,this.status=p.Connected,this.conn.connect(this.session.id),this.logger.log(`Started pinging session "${this.session.id}"`);this.session;)try{yield this.session.ping(),yield s(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=p.Disconnected,this.conn.close()}catch(e){this.logger.error("Failed to acquire Runner session. Will try again in 3s",e),yield s(c)}}}))}}function y(e,t){for(var n=0,i=e.length-1;i>=0;i--){var s=e[i];"."===s?e.splice(i,1):".."===s?(e.splice(i,1),n++):n&&(e.splice(i,1),n--)}if(t)for(;n--;n)e.unshift("..");return e}var C=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/,b=function(e){return C.exec(e).slice(1)};function S(){for(var e="",t=!1,n=arguments.length-1;n>=-1&&!t;n--){var i=n>=0?arguments[n]:"/";if("string"!=typeof i)throw new TypeError("Arguments to path.resolve must be strings");i&&(e=i+"/"+e,t="/"===i.charAt(0))}return(t?"/":"")+(e=y(k(e.split("/"),(function(e){return!!e})),!t).join("/"))||"."}function E(e){var t=w(e),n="/"===x(e,-1);return(e=y(k(e.split("/"),(function(e){return!!e})),!t).join("/"))||t||(e="."),e&&n&&(e+="/"),(t?"/":"")+e}function w(e){return"/"===e.charAt(0)}var I={extname:function(e){return b(e)[3]},basename:function(e,t){var n=b(e)[2];return t&&n.substr(-1*t.length)===t&&(n=n.substr(0,n.length-t.length)),n},dirname:function(e){var t=b(e),n=t[0],i=t[1];return n||i?(i&&(i=i.substr(0,i.length-1)),n+i):"."},sep:"/",delimiter:":",relative:function(e,t){function n(e){for(var t=0;t<e.length&&""===e[t];t++);for(var n=e.length-1;n>=0&&""===e[n];n--);return t>n?[]:e.slice(t,n-t+1)}e=S(e).substr(1),t=S(t).substr(1);for(var i=n(e.split("/")),s=n(t.split("/")),o=Math.min(i.length,s.length),r=o,a=0;a<o;a++)if(i[a]!==s[a]){r=a;break}var h=[];for(a=r;a<i.length;a++)h.push("..");return(h=h.concat(s.slice(r))).join("/")},join:function(){var e=Array.prototype.slice.call(arguments,0);return E(k(e,(function(e,t){if("string"!=typeof e)throw new TypeError("Arguments to path.join must be strings");return e})).join("/"))},isAbsolute:w,normalize:E,resolve:S};function k(e,t){if(e.filter)return e.filter(t);for(var n=[],i=0;i<e.length;i++)t(e[i],i,e)&&n.push(e[i]);return n}var R,x="b"==="ab".substr(-1)?function(e,t,n){return e.substr(t,n)}:function(e,t,n){return t<0&&(t=e.length+t),e.substr(t,n)};class F{get level(){return I.normalize(this.path).split(I.sep).length-1}}function _(e){return e.sort(((e,t)=>"Prompt"===e.type?-2:e.type!==t.type?"Dir"===e.type?-1:"Dir"===t.type?1:0:e.key.localeCompare(t.key))),e}class P extends F{constructor({name:e,parent:t,onAddItem:n}){super(),this.children=[],this.name=e,this.parent=t,this.addItemHandler=n,this.path=I.join(this.parent.path,this.name)}removeChildNode(e){this.children=this.children.filter((t=>t!==e))}serialize(e,t,n){const i=this.children.map((i=>i.serialize(e,t,n)));return{type:"Dir",key:this.path,title:e({name:this.name,onAddFileMouseDown:e=>{this.addItemHandler({event:e,dir:this,type:"File"})},onAddDirMouseDown:e=>{this.addItemHandler({event:e,dir:this,type:"Dir"})}}),children:_(i)}}}class N extends F{constructor({name:e,parent:t}){super(),this.name=e,this.parent=t,this.path=I.join(this.parent.path,this.name)}serialize(){return{type:"File",key:this.path,title:this.name,isLeaf:!0}}}class L extends F{constructor({parent:e,forNode:t,onConfirm:n,onBlur:i}){super(),this.name="name-prompt",this.parent=e,this.forNode=t,this.path=I.join(e.path,this.name),this.onConfirm=n,this.onBlur=i}serialize(e,t,n){return{type:"Prompt",key:this.path,title:t({onConfirm:e=>{var t;return null===(t=this.onConfirm)||void 0===t?void 0:t.call(this,this,e)},onBlur:()=>{var e;return null===(e=this.onBlur)||void 0===e?void 0:e.call(this,this)}}),isLeaf:!0,selectable:!1,icon:n({type:this.forNode})}}}class O extends F{constructor({onAddItem:e}){super(),this.name="/",this.path="/",this.parent=void 0,this.children=[],this.addItemHandler=e}serialize(e,t,n){const i=this.children.map((i=>i.serialize(e,t,n)));return{type:"Root",key:this.path,title:e({name:this.name,onAddFileMouseDown:e=>{this.addItemHandler({event:e,dir:this,type:"File"})},onAddDirMouseDown:e=>{this.addItemHandler({event:e,dir:this,type:"Dir"})}}),children:_(i)}}}class $ extends F{constructor({parent:e}){super(),this.name="empty-node",this.parent=e,this.path=I.join(this.parent.path,this.name)}serialize(){return{type:"Empty",key:this.path,title:"Empty Directory",isLeaf:!0,disabled:!0}}}class j{constructor(){this.logger=new n("Filesystem"),this.root=new O({onAddItem:({event:e,dir:t,type:n})=>this.showPrompt({event:e,parent:t,type:n})}),this.startingPrintIndent=0,this.onNewItemConfirmLs=[],this.onDirsChangeLs=[],this.onFileContentLs=[],this.onShowPromptLs=[]}removeAllListeners(){this.onNewItemConfirmLs=[],this.onDirsChangeLs=[],this.onFileContentLs=[],this.onShowPromptLs=[]}addListener(e,t){switch(e){case"onNewItemConfirm":this.onNewItemConfirmLs.push(t);break;case"onDirsChange":this.onDirsChangeLs.push(t);break;case"onFileContent":this.onFileContentLs.push(t);break;case"onShowPrompt":this.onShowPromptLs.push(t);break;default:throw new Error(`Unknown event type: ${e}`)}}removeListener(e,t){switch(e){case"onNewItemConfirm":this.onNewItemConfirmLs=this.onNewItemConfirmLs.filter((e=>e!==t));break;case"onDirsChange":this.onDirsChangeLs=this.onDirsChangeLs.filter((e=>e!==t));break;case"onFileContent":this.onFileContentLs=this.onFileContentLs.filter((e=>e!==t));break;case"onShowPrompt":this.onShowPromptLs=this.onShowPromptLs.filter((e=>e!==t));break;default:throw new Error(`Unknown event type: ${e}`)}}addNodeToDir(e,t){this.logger.log("Adding node to dir",{dirPath:e,node:t});let n=this.find(e);if(n||(this.logger.log("Dir not found, will make all",{dirPath:e}),n=this.mkAll(e)),!n)throw new Error("dirNode is undefined");if(!(n instanceof O||n instanceof P))throw new Error(`Node at '${e}' is not a directory or a root node`);if(n.children.some((e=>e.name===t.name)))return;let i;i="Dir"===t.type?new P({name:t.name,parent:n,onAddItem:({event:e,dir:t,type:n})=>this.showPrompt({event:e,parent:t,type:n})}):new N({name:t.name,parent:n}),1===n.children.length&&n.children[0]instanceof $?n.children=[i]:n.children.push(i),this.notifyOnDirsChangeLs({dirPaths:[e]})}removeNodeFromDir(e,t){this.logger.log("Remove node from dir",{dirPath:e,nodeName:t.name});const n=this.find(e);if(!n)throw new Error(`No node with path '${e}'`);if(!(n instanceof O||n instanceof P))throw new Error(`Node at '${e}' is not a directory or root node`);const i=n.children.length;n.children=n.children.filter((e=>e.name!==t.name));i!==n.children.length?(0===n.children.length&&(n.children=[new $({parent:n})]),this.notifyOnDirsChangeLs({dirPaths:[e]})):this.logger.warn("Node not found in dir",{dirPath:e,nodeName:t.name})}setFileContent(e){this.logger.log("Update file content",e),this.onFileContentLs.forEach((t=>t(e)))}setDirsContent(e){this.logger.log("Set dirs content",e);for(const t of e){let e=this.find(t.dirPath);if(e||(this.logger.log("Dir not found, will make all",{dirPath:t.dirPath}),e=this.mkAll(t.dirPath)),!e)throw new Error("dirNode is undefined");if(!(e instanceof O||e instanceof P))throw new Error(`Node at '${t.dirPath}' is not a directory or a root node`);const n=e.children.find((e=>e instanceof L));if(t.content.length){const n=[];for(const i of t.content){let t;t="Dir"===i.type?new P({name:i.name,parent:e,onAddItem:({event:e,dir:t,type:n})=>this.showPrompt({event:e,parent:t,type:n})}):new N({name:i.name,parent:e}),n.push(t)}e.children=n}else e.children=[new $({parent:e})];n&&e.children.push(n)}this.notifyOnDirsChangeLs({dirPaths:e.map((e=>e.dirPath))})}showPrompt(e){const{event:t,parent:n,type:i}=e;if(this.logger.log("Show prompt",{parent:n,type:i}),n.children.some((e=>e instanceof L)))return;t.preventDefault();const s=new L({parent:n,forNode:i,onConfirm:((e,t)=>{if(this.logger.log("Prompt confirm",{prompt:e,name:t}),!t)return;const n=e.parent.path,s=I.join(e.parent.path,t);this.removeFromParent(e),this.notifyOnDirsChangeLs({dirPaths:[n]}),this.notifyOnNewItemConfirmLs({fullPath:s,name:t,type:i})}).bind(this),onBlur:(e=>{this.logger.log("Prompt blur",{prompt:e});const t=e.parent.path;this.removeFromParent(e),this.notifyOnDirsChangeLs({dirPaths:[t]})}).bind(this)});n.children.push(s),this.notifyOnDirsChangeLs({dirPaths:[s.parent.path]}),this.notifyOnShowPromptLs({dirPath:s.parent.path})}serialize(e,t,n){return this.logger.log("Serialize"),[this.root.serialize(e,t,n)]}print(e=this.root,t=this.startingPrintIndent){const n=" ".repeat(t);console.log(n+e.path,`(${e.name})`);for(const i of e.children)i instanceof P?this.print(i,t+1):console.log(n+" "+i.path,`(${i.name})`)}find(e,t=this.root){if(this.logger.log("Find (recursion)",{currentPath:t.path,targetPath:e}),e=I.normalize(e),t.path===e)return t;const n=e.split(I.sep).length-1;if(!(t.level>n)&&(t instanceof O||t instanceof P))for(const n of t.children){const t=this.find(e,n);if(t)return t}}mkDir(e){this.logger.log("Make dir",e);const t=this.find(e.parentPath);if(!t)throw new Error(`Parent dir '${e.parentPath}' not found`);if(!(t instanceof O||t instanceof P))throw new Error("Parent is not a dir or root");const n=new P({parent:t,name:e.name,onAddItem:({event:e,dir:t,type:n})=>this.showPrompt({event:e,parent:t,type:n})});return t.children.push(n),n}mkAll(e){this.logger.log("Make all",e);const t=e.split(I.sep);let n,i="/";for(const e of t)if(i=I.join(i,e),!this.find(i)){const t=I.dirname(i);n=this.mkDir({parentPath:t,name:e})}return n}removeFromParent(e){const{parent:t}=e;(t instanceof O||t instanceof P)&&(t.children=t.children.filter((t=>t!==e))),e.parent=void 0}notifyOnShowPromptLs(e){this.logger.log("Notify on show prompt",e),this.onShowPromptLs.forEach((t=>t(e)))}notifyOnNewItemConfirmLs(e){this.logger.log("Notify on new item confirm",e),this.onNewItemConfirmLs.forEach((t=>t(e)))}notifyOnDirsChangeLs(e){this.logger.log("Notify on dirs change",e),this.onDirsChangeLs.forEach((t=>t(e)))}}function A(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)}!function(e){e[e.Stdout=0]="Stdout",e[e.Stderr=1]="Stderr"}(R||(R={}));class M{constructor(e,t){this.contextID=e,this.templateID=t,this.output=[],this.filesystem=new j,this.isReady=!1,this.id=`${e}_${A(t)}`,this.template=g[this.templateID]}restart(){this.output=[],this.isReady=!1,this.filesystem.setDirsContent([{dirPath:"/",content:[]}])}logOutput(e,t){this.output=[...this.output,{message:e,source:t}]}rootDir(){return this.template.root_dir}}function W(e,{environmentID:t,template:n}){const i={type:h.RunningEnvironment.Start,payload:{environmentID:t,template:n}};e.send(i)}function H(e,{environmentID:t,executionID:n,command:i}){const s={type:h.RunningEnvironment.ExecCmd,payload:{environmentID:t,executionID:n,command:i}};e.send(s)}function T(e,{environmentID:t,path:n,content:i}){const s={type:h.RunningEnvironment.WriteFile,payload:{environmentID:t,path:n,content:i}};e.send(s)}class z{constructor(e){var t,i;this.opts=e,this.fsWriteSubscribers=[],this.logger=new n(`EvaluationContext [${e.templateID}]`,e.debug),this.env=new M(this.contextID,e.templateID),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.opts.conn.sessionID&&this.handleConnectionOpen(this.opts.conn.sessionID),this.opts.conn.isClosed&&this.handleConnectionClose(),W(this.opts.conn,{environmentID:this.env.id,template:this.env.template}),null===(i=(t=this.opts).onEnvChange)||void 0===i||i.call(t,this.env)}get contextID(){return this.opts.contextID}restart(){this.logger.log("Restart",this.opts.conn.sessionID),this.env.restart(),W(this.opts.conn,{environmentID:this.env.id,template:this.env.template})}destroy(){this.logger.log("Destroy"),this.unsubscribeConnHandler(),this.env.filesystem.removeAllListeners(),this.fsWriteSubscribers=[]}getFile({path:e}){return i(this,void 0,void 0,(function*(){let t;this.logger.log("Get file",{filepath:e});const n=new Promise(((e,n)=>{t=e,setTimeout((()=>{n("Timeout")}),1e4)})),i=n=>{n.path.endsWith(e)&&t(n.content)};this.env.filesystem.addListener("onFileContent",i),function(e,{environmentID:t,path:n}){const i={type:h.RunningEnvironment.GetFile,payload:{environmentID:t,path:n}};e.send(i)}(this.opts.conn,{environmentID:this.env.id,path:e});try{return yield n}catch(t){throw new Error(`Error retrieving file ${e}: ${t}`)}finally{this.env.filesystem.removeListener("onFileContent",i)}}))}deleteFile({path:e}){this.logger.log("Delete file",{filepath:e}),function(e,{environmentID:t,path:n}){const i={type:h.RunningEnvironment.RemoveFile,payload:{environmentID:t,path:n}};e.send(i)}(this.opts.conn,{environmentID:this.env.id,path:e})}updateFile({path:e,content:t}){return i(this,void 0,void 0,(function*(){let n;this.logger.log("Update file",{filepath:e});const i=new Promise(((e,t)=>{n=e,setTimeout((()=>{t("Timeout")}),1e4)})),s=t=>{t.path.endsWith(e)&&n()};this.subscribeFSWrite(s),T(this.opts.conn,{environmentID:this.env.id,path:e,content:t});try{yield i}catch(t){throw new Error(`File ${e} not written to VM: ${t}`)}finally{this.unsubscribeFSWrite(s)}}))}createDir({path:e}){this.logger.log("Create dir",{filepath:e}),function(e,{environmentID:t,path:n}){const i={type:h.RunningEnvironment.CreateDir,payload:{environmentID:t,path:n}};e.send(i)}(this.opts.conn,{environmentID:this.env.id,path:e})}listDir({path:e}){this.logger.log("List dir",{filepath:e}),function(e,{environmentID:t,path:n}){const i={type:h.RunningEnvironment.ListDir,payload:{environmentID:t,path:n}};e.send(i)}(this.opts.conn,{environmentID:this.env.id,path:e})}executeCode({executionID:e,code:t}){this.logger.log("Execute code",{executionID:e});const n=g[this.env.templateID];if(void 0===n.toCommand)return;const i=`${e}${n.fileExtension}`,s=I.join("/src",i);T(this.opts.conn,{environmentID:this.env.id,path:s,content:t});const o=I.join(n.root_dir,s),r=n.toCommand(o);H(this.opts.conn,{environmentID:this.env.id,executionID:e,command:r})}executeCommand({executionID:e,command:t}){this.logger.log("Execute shell command",{executionID:e,command:t}),H(this.opts.conn,{environmentID:this.env.id,executionID:e,command:t})}subscribeFSWrite(e){this.fsWriteSubscribers.push(e)}unsubscribeFSWrite(e){const t=this.fsWriteSubscribers.indexOf(e);t>-1&&this.fsWriteSubscribers.splice(t,1)}handleConnectionOpen(e){var t,n;this.restart(),null===(n=(t=this.opts).onSessionChange)||void 0===n||n.call(t,{status:p.Connected,sessionID:e})}handleConnectionClose(){var e,t;null===(t=(e=this.opts).onSessionChange)||void 0===t||t.call(e,{status:p.Connecting})}handleConnectionMessage(e){switch(this.logger.log("Handling message from remote Runner",{message:e}),e.type){case h.RunningEnvironment.StartAck:{const t=e;this.vmenv_handleStartAck(t.payload);break}case h.RunningEnvironment.CmdOut:{const t=e;this.vmenv_handleCmdOut(t.payload);break}case h.RunningEnvironment.CmdExit:{const t=e;this.vmenv_handleCmdExit(t.payload);break}case h.RunningEnvironment.FSEventWrite:{const t=e;this.vmenv_handleFSEventWrite(t.payload);break}case h.RunningEnvironment.FileContent:{const t=e;this.vmenv_handleFileContent(t.payload);break}case h.RunningEnvironment.FSEventCreate:{const t=e;this.vmenv_handleFSEventCreate(t.payload);break}case h.RunningEnvironment.FSEventRemove:{const t=e;this.vmenv_handleFSEventRemove(t.payload);break}case h.RunningEnvironment.DirContent:{const t=e;this.vmenv_handleDirContent(t.payload);break}case h.RunningEnvironment.Stderr:{const t=e;this.vmenv_handleStderr(t.payload);break}case h.RunningEnvironment.Stdout:{const t=e;this.vmenv_handleStdout(t.payload);break}default:this.logger.warn("Unknown message type",{message:e})}}vmenv_handleFSEventCreate(e){this.logger.log('[vmenv] Handling "FSEventCreate"',e);const t=I.basename(e.path),n=I.dirname(e.path),i="Directory"===e.type?"Dir":"File";this.env.filesystem.addNodeToDir(n,{name:t,type:i})}vmenv_handleFSEventRemove(e){this.logger.log('[vmenv] Handling "FSEventRemove"',{payload:e});const t=I.basename(e.path),n=I.dirname(e.path);this.env.filesystem.removeNodeFromDir(n,{name:t})}vmenv_handleDirContent(e){this.logger.log('[vmenv] Handling "DirContent"',e);const t=[];for(const n of e.content){const e=I.basename(n.path),i="Directory"===n.type?"Dir":"File";t.push({name:e,type:i})}this.env.filesystem.setDirsContent([{dirPath:e.dirPath,content:t}])}vmenv_handleCmdExit(e){var t,n;this.logger.log('[vmenv] Handling "CmdExit"',e),void 0!==e.error&&(null===(n=(t=this.opts).onCmdOut)||void 0===n||n.call(t,{environmentID:e.environmentID,executionID:e.executionID,stderr:e.error}))}vmenv_handleFSEventWrite(e){this.logger.log('[vmenv] Handling "FSEventWrite"',e),this.fsWriteSubscribers.forEach((t=>t(e)))}vmenv_handleFileContent(e){this.logger.log('[vmenv] Handling "FileContent"',{environmentID:e.environmentID,path:e.path}),this.env.filesystem.setFileContent(e)}vmenv_handleStartAck(e){var t,n;this.logger.log('[vmenv] Handling "StartAck"',{payload:e}),this.env.isReady=!0,null===(n=(t=this.opts).onEnvChange)||void 0===n||n.call(t,this.env)}vmenv_handleCmdOut(e){var t,n;this.logger.log('[vmenv] Handling "CmdOut"',e),null===(n=(t=this.opts).onCmdOut)||void 0===n||n.call(t,e)}vmenv_handleStderr(e){this.logger.log('[vmenv] Handling "Stderr"',e),this.env.logOutput(e.message,R.Stderr)}vmenv_handleStdout(e){this.logger.log('[vmenv] Handling "Stdout"',e),this.env.logOutput(e.message,R.Stdout)}}class q{constructor(){this.logger=new n("Runner"),this.conn=new m,this.sessManager=new D(this.conn)}static get obj(){return q._obj||(q._obj=new q)}get session(){return this.sessManager.session}get status(){return this.sessManager.status}reset(){this.logger.log("Reset"),this.sessManager.reset()}createContext(e){return new z(Object.assign(Object.assign({},e),{conn:this.conn}))}__debug__loadNewSession(){this.logger.log("__debug__loadNewSession"),this.sessManager.reset()}}const G=(U="1234567890abcdefghijklmnopqrstuvwxyz",B=6,()=>{let e="",t=B;for(;t--;)e+=U[Math.random()*U.length|0];return e});var U,B,V;e.DevbookStatus=void 0,(V=e.DevbookStatus||(e.DevbookStatus={}))[V.Disconnected=0]="Disconnected",V[V.Connecting=1]="Connecting",V[V.Connected=2]="Connected";class J{constructor(t){this.opts=t,this.contextID="default",this.executionID=G(),this._isDestroyed=!1,this._isEnvReady=!1,this._sessionStatus=p.Disconnected,this._status=e.DevbookStatus.Disconnected;const n=this.getURL.bind(this),i=()=>this.opts.env,s=()=>this.executionID,o=e=>this.isEnvReady=e,r=e=>this.sessionStatus=e,a=e=>this.sessionID=e;this.context=q.obj.createContext({debug:t.debug,templateID:t.env,contextID:this.contextID,onEnvChange(e){var s;e.templateID===i()&&(o(e.isReady),null===(s=t.onURLChange)||void 0===s||s.call(t,n))},onSessionChange({status:e,sessionID:i}){var s;a(i),r(e),null===(s=t.onURLChange)||void 0===s||s.call(t,n)},onCmdOut(e){var n,i;e.executionID===s()&&(void 0!==e.stdout&&(null===(n=t.onStdout)||void 0===n||n.call(t,e.stdout)),void 0!==e.stderr&&(null===(i=t.onStderr)||void 0===i||i.call(t,e.stderr)))}})}get sessionID(){return this._sessionID}set sessionID(e){this._sessionID=e}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)}get env(){return this.context.env}get fs(){const e=this.env.filesystem;return{delete:this.deleteFile.bind(this),listDir:this.listDir.bind(this),createDir:this.createDir.bind(this),get:this.getFile.bind(this),write:this.writeFile.bind(this),addListener:e.addListener.bind(e),removeListener:e.removeListener.bind(e),serialize:e.serialize.bind(e)}}getURL(t){if(this.status===e.DevbookStatus.Connected&&this.sessionID&&this.env.isReady)return`https://${t}-${this.env.id}-${this.sessionID}.o.usedevbook.com`}runCmd(t){if(this.status!==e.DevbookStatus.Connected)throw new Error("Not connected to the VM yet.");this.executionID=G(),this.context.executeCommand({executionID:this.executionID,command:t})}runCode(t){if(this.status!==e.DevbookStatus.Connected)throw new Error("Not connected to the VM yet.");this.executionID=G(),this.context.executeCode({executionID:this.executionID,code:t})}destroy(){this.context.destroy(),this.isDestroyed=!0}listDir(t){if(this.status!==e.DevbookStatus.Connected)throw new Error("Not connected to the VM yet.");return this.context.listDir({path:t})}createDir(t){if(this.status!==e.DevbookStatus.Connected)throw new Error("Not connected to the VM yet.");return this.context.createDir({path:t})}deleteFile(t){if(this.status!==e.DevbookStatus.Connected)throw new Error("Not connected to the VM yet.");return this.context.deleteFile({path:t})}getFile(t){if(this.status!==e.DevbookStatus.Connected)throw new Error("Not connected to the VM yet.");return this.context.getFile({path:t})}writeFile(t,n){if(this.status!==e.DevbookStatus.Connected)throw new Error("Not connected to the VM yet.");return this.context.updateFile({path:t,content:n})}updateStatus(){if(this.isDestroyed)return void(this.status!==e.DevbookStatus.Disconnected&&(this.status=e.DevbookStatus.Disconnected));let t;switch(this.sessionStatus){case p.Disconnected:t=e.DevbookStatus.Disconnected;break;case p.Connecting:t=e.DevbookStatus.Connecting;break;case p.Connected:if(!this.isEnvReady){t=e.DevbookStatus.Connecting;break}t=e.DevbookStatus.Connected}this.status=t}}e.Devbook=J,e.useDevbook=function({env:n,debug:i,port:s}){const[o,r]=t.useState(e.DevbookStatus.Disconnected),[a,h]=t.useState([]),[l,d]=t.useState([]),[c,u]=t.useState(),g=t.useMemo((()=>(d([]),h([]),u(void 0),new J({debug:i,env:n,onStatusChange(e){r(e)},onStderr(e){h((t=>[...t,e]))},onStdout(e){d((t=>[...t,e]))},onURLChange(e){s&&u(e(s))}}))),[n,i,s]),m=t.useCallback((e=>{d([]),h([]),g.runCmd(e)}),[g]),v=t.useCallback((e=>{d([]),h([]),g.runCode(e)}),[g]);return t.useEffect((function(){return()=>g.destroy()}),[g]),{stderr:a,stdout:l,runCmd:m,runCode:v,status:o,fs:g.fs,url:c}},Object.defineProperty(e,"__esModule",{value:!0})}));
***************************************************************************** */function i(e,t,n,i){return new(n||(n=Promise))((function(s,o){function r(e){try{h(i.next(e))}catch(e){o(e)}}function a(e){try{h(i.throw(e))}catch(e){o(e)}}function h(e){var t;e.done?s(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(r,a)}h((i=i.apply(e,t||[])).next())}))}function s(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",e.RunCode="RunningEnvironment.Run"}(r||(r={})),function(e){e.Error="CodeCell.Error"}(a||(a={}));const h={Runner:o,RunningEnvironment:r,CodeCell:a},l="orchestrator.usedevbook.com",d="dbk_sdk_session_id",c=3e3;class u{constructor(){this.url=`wss://${l}`,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.sessionID),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(e){var t;this.logger.log("Connection opened",{readyState:null===(t=this.client)||void 0===t?void 0:t.readyState}),this.handlers.forEach((t=>t.onOpen(e)))}_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 i(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 s(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(h.RunningEnvironment).includes(n.type)||Object.values(h.Runner).includes(n.type)||Object.values(h.CodeCell).includes(n.type)?n.type!==h.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 g,m;!function(e){e.Ok="Ok",e.Terminated="Terminated"}(g||(g={}));class v{constructor(e,t=new Date){this.id=e,this.lastPing=t,this.logger=new n("RunnerSession"),this.url=`https://${l}`}ping(){return i(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===g.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 p{constructor(e){this.conn=e,this.logger=new n("SessionManager"),this.url=`https://${l}`,this.isGettingSessionActive=!1,this.status=m.Disconnected,this.logger.log("Initialize"),this.getSession()}get cachedSessionID(){return sessionStorage.getItem(d)}set cachedSessionID(e){null===e?(this.logger.log("Cleared last sessionID"),sessionStorage.removeItem(d)):(this.logger.log(`Saved sessionID "${e}" as last sessionID`),sessionStorage.setItem(d,e))}reset(){this.logger.log("Reset"),this.status=m.Disconnected,this.cachedSessionID=null,this.conn.close(),this.session=void 0}getSession(){var e;return i(this,void 0,void 0,(function*(){if(!this.isGettingSessionActive)for(this.isGettingSessionActive=!0;;){this.status=m.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),i=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,i),yield s(c);continue}for(this.session=new v(i.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 s(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 s(c)}}}))}}function f(e,t){for(var n=0,i=e.length-1;i>=0;i--){var s=e[i];"."===s?e.splice(i,1):".."===s?(e.splice(i,1),n++):n&&(e.splice(i,1),n--)}if(t)for(;n--;n)e.unshift("..");return e}var D=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/,y=function(e){return D.exec(e).slice(1)};function C(){for(var e="",t=!1,n=arguments.length-1;n>=-1&&!t;n--){var i=n>=0?arguments[n]:"/";if("string"!=typeof i)throw new TypeError("Arguments to path.resolve must be strings");i&&(e=i+"/"+e,t="/"===i.charAt(0))}return(t?"/":"")+(e=f(E(e.split("/"),(function(e){return!!e})),!t).join("/"))||"."}function S(e){var t=b(e),n="/"===R(e,-1);return(e=f(E(e.split("/"),(function(e){return!!e})),!t).join("/"))||t||(e="."),e&&n&&(e+="/"),(t?"/":"")+e}function b(e){return"/"===e.charAt(0)}var w={extname:function(e){return y(e)[3]},basename:function(e,t){var n=y(e)[2];return t&&n.substr(-1*t.length)===t&&(n=n.substr(0,n.length-t.length)),n},dirname:function(e){var t=y(e),n=t[0],i=t[1];return n||i?(i&&(i=i.substr(0,i.length-1)),n+i):"."},sep:"/",delimiter:":",relative:function(e,t){function n(e){for(var t=0;t<e.length&&""===e[t];t++);for(var n=e.length-1;n>=0&&""===e[n];n--);return t>n?[]:e.slice(t,n-t+1)}e=C(e).substr(1),t=C(t).substr(1);for(var i=n(e.split("/")),s=n(t.split("/")),o=Math.min(i.length,s.length),r=o,a=0;a<o;a++)if(i[a]!==s[a]){r=a;break}var h=[];for(a=r;a<i.length;a++)h.push("..");return(h=h.concat(s.slice(r))).join("/")},join:function(){var e=Array.prototype.slice.call(arguments,0);return S(E(e,(function(e,t){if("string"!=typeof e)throw new TypeError("Arguments to path.join must be strings");return e})).join("/"))},isAbsolute:b,normalize:S,resolve:C};function E(e,t){if(e.filter)return e.filter(t);for(var n=[],i=0;i<e.length;i++)t(e[i],i,e)&&n.push(e[i]);return n}var I,R="b"==="ab".substr(-1)?function(e,t,n){return e.substr(t,n)}:function(e,t,n){return t<0&&(t=e.length+t),e.substr(t,n)};class k{get level(){return w.normalize(this.path).split(w.sep).length-1}}function F(e){return e.sort(((e,t)=>"Prompt"===e.type?-2:e.type!==t.type?"Dir"===e.type?-1:"Dir"===t.type?1:0:e.key.localeCompare(t.key))),e}class P extends k{constructor({name:e,parent:t,onAddItem:n}){super(),this.children=[],this.name=e,this.parent=t,this.addItemHandler=n,this.path=w.join(this.parent.path,this.name)}removeChildNode(e){this.children=this.children.filter((t=>t!==e))}serialize(e,t,n){const i=this.children.map((i=>i.serialize(e,t,n)));return{type:"Dir",key:this.path,title:e({name:this.name,onAddFileMouseDown:e=>{this.addItemHandler({event:e,dir:this,type:"File"})},onAddDirMouseDown:e=>{this.addItemHandler({event:e,dir:this,type:"Dir"})}}),children:F(i)}}}class x extends k{constructor({name:e,parent:t}){super(),this.name=e,this.parent=t,this.path=w.join(this.parent.path,this.name)}serialize(){return{type:"File",key:this.path,title:this.name,isLeaf:!0}}}class L extends k{constructor({parent:e,forNode:t,onConfirm:n,onBlur:i}){super(),this.name="name-prompt",this.parent=e,this.forNode=t,this.path=w.join(e.path,this.name),this.onConfirm=n,this.onBlur=i}serialize(e,t,n){return{type:"Prompt",key:this.path,title:t({onConfirm:e=>{var t;return null===(t=this.onConfirm)||void 0===t?void 0:t.call(this,this,e)},onBlur:()=>{var e;return null===(e=this.onBlur)||void 0===e?void 0:e.call(this,this)}}),isLeaf:!0,selectable:!1,icon:n({type:this.forNode})}}}class O extends k{constructor({onAddItem:e}){super(),this.name="/",this.path="/",this.parent=void 0,this.children=[],this.addItemHandler=e}serialize(e,t,n){const i=this.children.map((i=>i.serialize(e,t,n)));return{type:"Root",key:this.path,title:e({name:this.name,onAddFileMouseDown:e=>{this.addItemHandler({event:e,dir:this,type:"File"})},onAddDirMouseDown:e=>{this.addItemHandler({event:e,dir:this,type:"Dir"})}}),children:F(i)}}}class N extends k{constructor({parent:e}){super(),this.name="empty-node",this.parent=e,this.path=w.join(this.parent.path,this.name)}serialize(){return{type:"Empty",key:this.path,title:"Empty Directory",isLeaf:!0,disabled:!0}}}class _{constructor(){this.logger=new n("Filesystem"),this.root=new O({onAddItem:({event:e,dir:t,type:n})=>this.showPrompt({event:e,parent:t,type:n})}),this.startingPrintIndent=0,this.onNewItemConfirmLs=[],this.onDirsChangeLs=[],this.onFileContentLs=[],this.onShowPromptLs=[]}removeAllListeners(){this.onNewItemConfirmLs=[],this.onDirsChangeLs=[],this.onFileContentLs=[],this.onShowPromptLs=[]}addListener(e,t){switch(e){case"onNewItemConfirm":this.onNewItemConfirmLs.push(t);break;case"onDirsChange":this.onDirsChangeLs.push(t);break;case"onFileContent":this.onFileContentLs.push(t);break;case"onShowPrompt":this.onShowPromptLs.push(t);break;default:throw new Error(`Unknown event type: ${e}`)}}removeListener(e,t){switch(e){case"onNewItemConfirm":this.onNewItemConfirmLs=this.onNewItemConfirmLs.filter((e=>e!==t));break;case"onDirsChange":this.onDirsChangeLs=this.onDirsChangeLs.filter((e=>e!==t));break;case"onFileContent":this.onFileContentLs=this.onFileContentLs.filter((e=>e!==t));break;case"onShowPrompt":this.onShowPromptLs=this.onShowPromptLs.filter((e=>e!==t));break;default:throw new Error(`Unknown event type: ${e}`)}}addNodeToDir(e,t){this.logger.log("Adding node to dir",{dirPath:e,node:t});let n=this.find(e);if(n||(this.logger.log("Dir not found, will make all",{dirPath:e}),n=this.mkAll(e)),!n)throw new Error("dirNode is undefined");if(!(n instanceof O||n instanceof P))throw new Error(`Node at '${e}' is not a directory or a root node`);if(n.children.some((e=>e.name===t.name)))return;let i;i="Dir"===t.type?new P({name:t.name,parent:n,onAddItem:({event:e,dir:t,type:n})=>this.showPrompt({event:e,parent:t,type:n})}):new x({name:t.name,parent:n}),1===n.children.length&&n.children[0]instanceof N?n.children=[i]:n.children.push(i),this.notifyOnDirsChangeLs({dirPaths:[e]})}removeNodeFromDir(e,t){this.logger.log("Remove node from dir",{dirPath:e,nodeName:t.name});const n=this.find(e);if(!n)throw new Error(`No node with path '${e}'`);if(!(n instanceof O||n instanceof P))throw new Error(`Node at '${e}' is not a directory or root node`);const i=n.children.length;n.children=n.children.filter((e=>e.name!==t.name));i!==n.children.length?(0===n.children.length&&(n.children=[new N({parent:n})]),this.notifyOnDirsChangeLs({dirPaths:[e]})):this.logger.warn("Node not found in dir",{dirPath:e,nodeName:t.name})}setFileContent(e){this.logger.log("Update file content",e),this.onFileContentLs.forEach((t=>t(e)))}setDirsContent(e){this.logger.log("Set dirs content",e);for(const t of e){let e=this.find(t.dirPath);if(e||(this.logger.log("Dir not found, will make all",{dirPath:t.dirPath}),e=this.mkAll(t.dirPath)),!e)throw new Error("dirNode is undefined");if(!(e instanceof O||e instanceof P))throw new Error(`Node at '${t.dirPath}' is not a directory or a root node`);const n=e.children.find((e=>e instanceof L));if(t.content.length){const n=[];for(const i of t.content){let t;t="Dir"===i.type?new P({name:i.name,parent:e,onAddItem:({event:e,dir:t,type:n})=>this.showPrompt({event:e,parent:t,type:n})}):new x({name:i.name,parent:e}),n.push(t)}e.children=n}else e.children=[new N({parent:e})];n&&e.children.push(n)}this.notifyOnDirsChangeLs({dirPaths:e.map((e=>e.dirPath))})}showPrompt(e){const{event:t,parent:n,type:i}=e;if(this.logger.log("Show prompt",{parent:n,type:i}),n.children.some((e=>e instanceof L)))return;t.preventDefault();const s=new L({parent:n,forNode:i,onConfirm:((e,t)=>{if(this.logger.log("Prompt confirm",{prompt:e,name:t}),!t)return;const n=e.parent.path,s=w.join(e.parent.path,t);this.removeFromParent(e),this.notifyOnDirsChangeLs({dirPaths:[n]}),this.notifyOnNewItemConfirmLs({fullPath:s,name:t,type:i})}).bind(this),onBlur:(e=>{this.logger.log("Prompt blur",{prompt:e});const t=e.parent.path;this.removeFromParent(e),this.notifyOnDirsChangeLs({dirPaths:[t]})}).bind(this)});n.children.push(s),this.notifyOnDirsChangeLs({dirPaths:[s.parent.path]}),this.notifyOnShowPromptLs({dirPath:s.parent.path})}serialize(e,t,n){return this.logger.log("Serialize"),[this.root.serialize(e,t,n)]}print(e=this.root,t=this.startingPrintIndent){const n=" ".repeat(t);console.log(n+e.path,`(${e.name})`);for(const i of e.children)i instanceof P?this.print(i,t+1):console.log(n+" "+i.path,`(${i.name})`)}find(e,t=this.root){if(this.logger.log("Find (recursion)",{currentPath:t.path,targetPath:e}),e=w.normalize(e),t.path===e)return t;const n=e.split(w.sep).length-1;if(!(t.level>n)&&(t instanceof O||t instanceof P))for(const n of t.children){const t=this.find(e,n);if(t)return t}}mkDir(e){this.logger.log("Make dir",e);const t=this.find(e.parentPath);if(!t)throw new Error(`Parent dir '${e.parentPath}' not found`);if(!(t instanceof O||t instanceof P))throw new Error("Parent is not a dir or root");const n=new P({parent:t,name:e.name,onAddItem:({event:e,dir:t,type:n})=>this.showPrompt({event:e,parent:t,type:n})});return t.children.push(n),n}mkAll(e){this.logger.log("Make all",e);const t=e.split(w.sep);let n,i="/";for(const e of t)if(i=w.join(i,e),!this.find(i)){const t=w.dirname(i);n=this.mkDir({parentPath:t,name:e})}return n}removeFromParent(e){const{parent:t}=e;(t instanceof O||t instanceof P)&&(t.children=t.children.filter((t=>t!==e))),e.parent=void 0}notifyOnShowPromptLs(e){this.logger.log("Notify on show prompt",e),this.onShowPromptLs.forEach((t=>t(e)))}notifyOnNewItemConfirmLs(e){this.logger.log("Notify on new item confirm",e),this.onNewItemConfirmLs.forEach((t=>t(e)))}notifyOnDirsChangeLs(e){this.logger.log("Notify on dirs change",e),this.onDirsChangeLs.forEach((t=>t(e)))}}function $(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)}!function(e){e[e.Stdout=0]="Stdout",e[e.Stderr=1]="Stderr"}(I||(I={}));class A{constructor(e,t){this.contextID=e,this.templateID=t,this.output=[],this.filesystem=new _,this.isReady=!1,this.id=`${e}_${$(t)}`}restart(){this.output=[],this.isReady=!1,this.filesystem.setDirsContent([{dirPath:"/",content:[]}])}logOutput(e,t){this.output=[...this.output,{message:e,source:t}]}}function M(e,{environmentID:t,templateID:n}){const i={type:h.RunningEnvironment.Start,payload:{environmentID:t,templateID:n}};e.send(i)}class W{constructor(e){var t,i;this.opts=e,this.fsWriteSubscribers=[],this.fileContentSubscribers=[],this.logger=new n(`EvaluationContext [${e.templateID}]`,e.debug),this.env=new A(this.contextID,e.templateID);this.unsubscribeConnHandler=this.opts.conn.subscribeHandler({onOpen:e=>this.handleConnectionOpen(e),onMessage:e=>this.handleConnectionMessage(e),onClose:()=>this.handleConnectionClose()}),this.opts.conn.isOpen&&this.opts.conn.sessionID&&this.handleConnectionOpen(this.opts.conn.sessionID),this.opts.conn.isClosed&&this.handleConnectionClose(),M(this.opts.conn,{environmentID:this.env.id,templateID:this.env.templateID}),null===(i=(t=this.opts).onEnvChange)||void 0===i||i.call(t,this.env)}get contextID(){return this.opts.contextID}restart(){this.logger.log("Restart",this.opts.conn.sessionID),this.env.restart(),M(this.opts.conn,{environmentID:this.env.id,templateID:this.env.templateID})}destroy(){this.logger.log("Destroy"),this.unsubscribeConnHandler(),this.fsWriteSubscribers=[],this.fileContentSubscribers=[]}getFile({path:e}){return i(this,void 0,void 0,(function*(){let t;this.logger.log("Get file",{filepath:e});const n=new Promise(((e,n)=>{t=e,setTimeout((()=>{n("Timeout")}),1e4)})),i=n=>{n.path.endsWith(e)&&t(n.content)};this.subscribeFileContent(i),function(e,{environmentID:t,path:n}){const i={type:h.RunningEnvironment.GetFile,payload:{environmentID:t,path:n}};e.send(i)}(this.opts.conn,{environmentID:this.env.id,path:e});try{return yield n}catch(t){throw new Error(`Error retrieving file ${e}: ${t}`)}finally{this.unsubscribeFileContent(i)}}))}deleteFile({path:e}){this.logger.log("Delete file",{filepath:e}),function(e,{environmentID:t,path:n}){const i={type:h.RunningEnvironment.RemoveFile,payload:{environmentID:t,path:n}};e.send(i)}(this.opts.conn,{environmentID:this.env.id,path:e})}updateFile({path:e,content:t}){return i(this,void 0,void 0,(function*(){let n;this.logger.log("Update file",{filepath:e});const i=new Promise(((e,t)=>{n=e,setTimeout((()=>{t("Timeout")}),1e4)})),s=t=>{t.path.endsWith(e)&&n()};this.subscribeFSWrite(s),function(e,{environmentID:t,path:n,content:i}){const s={type:h.RunningEnvironment.WriteFile,payload:{environmentID:t,path:n,content:i}};e.send(s)}(this.opts.conn,{environmentID:this.env.id,path:e,content:t});try{yield i}catch(t){throw new Error(`File ${e} not written to VM: ${t}`)}finally{this.unsubscribeFSWrite(s)}}))}createDir({path:e}){this.logger.log("Create dir",{filepath:e}),function(e,{environmentID:t,path:n}){const i={type:h.RunningEnvironment.CreateDir,payload:{environmentID:t,path:n}};e.send(i)}(this.opts.conn,{environmentID:this.env.id,path:e})}listDir({path:e}){this.logger.log("List dir",{filepath:e}),function(e,{environmentID:t,path:n}){const i={type:h.RunningEnvironment.ListDir,payload:{environmentID:t,path:n}};e.send(i)}(this.opts.conn,{environmentID:this.env.id,path:e})}executeCommand({executionID:e,command:t}){this.logger.log("Execute shell command",{executionID:e,command:t}),function(e,{environmentID:t,executionID:n,command:i}){const s={type:h.RunningEnvironment.ExecCmd,payload:{environmentID:t,executionID:n,command:i}};e.send(s)}(this.opts.conn,{environmentID:this.env.id,executionID:e,command:t})}subscribeFileContent(e){this.fileContentSubscribers.push(e)}unsubscribeFileContent(e){const t=this.fileContentSubscribers.indexOf(e);t>-1&&this.fileContentSubscribers.splice(t,1)}subscribeFSWrite(e){this.fsWriteSubscribers.push(e)}unsubscribeFSWrite(e){const t=this.fsWriteSubscribers.indexOf(e);t>-1&&this.fsWriteSubscribers.splice(t,1)}handleConnectionOpen(e){var t,n;this.restart(),null===(n=(t=this.opts).onSessionChange)||void 0===n||n.call(t,{status:m.Connected,sessionID:e})}handleConnectionClose(){var e,t;null===(t=(e=this.opts).onSessionChange)||void 0===t||t.call(e,{status:m.Connecting})}handleConnectionMessage(e){switch(this.logger.log("Handling message from remote Runner",{message:e}),e.type){case h.RunningEnvironment.StartAck:{const t=e;this.vmenv_handleStartAck(t.payload);break}case h.RunningEnvironment.CmdOut:{const t=e;this.vmenv_handleCmdOut(t.payload);break}case h.RunningEnvironment.CmdExit:{const t=e;this.vmenv_handleCmdExit(t.payload);break}case h.RunningEnvironment.FSEventWrite:{const t=e;this.vmenv_handleFSEventWrite(t.payload);break}case h.RunningEnvironment.FileContent:{const t=e;this.vmenv_handleFileContent(t.payload);break}case h.RunningEnvironment.FSEventCreate:{const t=e;this.vmenv_handleFSEventCreate(t.payload);break}case h.RunningEnvironment.FSEventRemove:{const t=e;this.vmenv_handleFSEventRemove(t.payload);break}case h.RunningEnvironment.DirContent:{const t=e;this.vmenv_handleDirContent(t.payload);break}case h.RunningEnvironment.Stderr:{const t=e;this.vmenv_handleStderr(t.payload);break}case h.RunningEnvironment.Stdout:{const t=e;this.vmenv_handleStdout(t.payload);break}default:this.logger.warn("Unknown message type",{message:e})}}vmenv_handleFSEventCreate(e){this.logger.log('[vmenv] Handling "FSEventCreate"',e);const t=w.basename(e.path),n=w.dirname(e.path),i="Directory"===e.type?"Dir":"File";this.env.filesystem.addNodeToDir(n,{name:t,type:i})}vmenv_handleFSEventRemove(e){this.logger.log('[vmenv] Handling "FSEventRemove"',{payload:e});const t=w.basename(e.path),n=w.dirname(e.path);this.env.filesystem.removeNodeFromDir(n,{name:t})}vmenv_handleDirContent(e){this.logger.log('[vmenv] Handling "DirContent"',e);const t=[];for(const n of e.content){const e=w.basename(n.path),i="Directory"===n.type?"Dir":"File";t.push({name:e,type:i})}this.env.filesystem.setDirsContent([{dirPath:e.dirPath,content:t}])}vmenv_handleCmdExit(e){var t,n;this.logger.log('[vmenv] Handling "CmdExit"',e),void 0!==e.error&&(null===(n=(t=this.opts).onCmdOut)||void 0===n||n.call(t,{environmentID:e.environmentID,executionID:e.executionID,stderr:e.error}))}vmenv_handleFSEventWrite(e){this.logger.log('[vmenv] Handling "FSEventWrite"',e),this.fsWriteSubscribers.forEach((t=>t(e)))}vmenv_handleFileContent(e){this.logger.log('[vmenv] Handling "FileContent"',{environmentID:e.environmentID,path:e.path}),this.fileContentSubscribers.forEach((t=>t(e)))}vmenv_handleStartAck(e){var t,n;this.logger.log('[vmenv] Handling "StartAck"',{payload:e}),this.env.isReady=!0,null===(n=(t=this.opts).onEnvChange)||void 0===n||n.call(t,this.env)}vmenv_handleCmdOut(e){var t,n;this.logger.log('[vmenv] Handling "CmdOut"',e),null===(n=(t=this.opts).onCmdOut)||void 0===n||n.call(t,e)}vmenv_handleStderr(e){this.logger.log('[vmenv] Handling "Stderr"',e),this.env.logOutput(e.message,I.Stderr)}vmenv_handleStdout(e){this.logger.log('[vmenv] Handling "Stdout"',e),this.env.logOutput(e.message,I.Stdout)}}class j{constructor(){this.logger=new n("Runner"),this.conn=new u,this.sessManager=new p(this.conn)}static get obj(){return j._obj||(j._obj=new j)}get session(){return this.sessManager.session}get status(){return this.sessManager.status}reset(){this.logger.log("Reset"),this.sessManager.reset()}createContext(e){return new W(Object.assign(Object.assign({},e),{conn:this.conn}))}__debug__loadNewSession(){this.logger.log("__debug__loadNewSession"),this.sessManager.reset()}}const H=(T="1234567890abcdefghijklmnopqrstuvwxyz",z=6,()=>{let e="",t=z;for(;t--;)e+=T[Math.random()*T.length|0];return e});var T,z,G;e.DevbookStatus=void 0,(G=e.DevbookStatus||(e.DevbookStatus={})).Disconnected="Disconnected",G.Connecting="Connecting",G.Connected="Connected";class U{constructor(t){this.opts=t,this.contextID="default",this.executionID=H(),this._isDestroyed=!1,this._isEnvReady=!1,this._sessionStatus=m.Disconnected,this._status=e.DevbookStatus.Disconnected;const n=this.getURL.bind(this),i=()=>this.opts.env,s=()=>this.executionID,o=e=>this.isEnvReady=e,r=e=>this.sessionStatus=e,a=e=>this.sessionID=e;this.context=j.obj.createContext({debug:t.debug,templateID:t.env,contextID:this.contextID,onEnvChange(e){var s;e.templateID===i()&&(o(e.isReady),null===(s=t.onURLChange)||void 0===s||s.call(t,n))},onSessionChange({status:e,sessionID:i}){var s;a(i),r(e),null===(s=t.onURLChange)||void 0===s||s.call(t,n)},onCmdOut(e){var n,i;e.executionID===s()&&(void 0!==e.stdout&&(null===(n=t.onStdout)||void 0===n||n.call(t,e.stdout)),void 0!==e.stderr&&(null===(i=t.onStderr)||void 0===i||i.call(t,e.stderr)))}})}get sessionID(){return this._sessionID}set sessionID(e){this._sessionID=e}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)}get env(){return this.context.env}get fs(){const e=this.env.filesystem;return{delete:this.deleteFile.bind(this),listDir:this.listDir.bind(this),createDir:this.createDir.bind(this),get:this.getFile.bind(this),write:this.writeFile.bind(this),addListener:e.addListener.bind(e),removeListener:e.removeListener.bind(e),serialize:e.serialize.bind(e)}}getURL(t){if(this.status===e.DevbookStatus.Connected&&this.sessionID&&this.env.isReady)return`https://${t}-${this.env.id}-${this.sessionID}.o.usedevbook.com`}runCmd(t){if(this.status!==e.DevbookStatus.Connected)throw new Error("Not connected to the VM yet.");this.executionID=H(),this.context.executeCommand({executionID:this.executionID,command:t})}destroy(){this.context.destroy(),this.isDestroyed=!0}listDir(t){if(this.status!==e.DevbookStatus.Connected)throw new Error("Not connected to the VM yet.");return this.context.listDir({path:t})}createDir(t){if(this.status!==e.DevbookStatus.Connected)throw new Error("Not connected to the VM yet.");return this.context.createDir({path:t})}deleteFile(t){if(this.status!==e.DevbookStatus.Connected)throw new Error("Not connected to the VM yet.");return this.context.deleteFile({path:t})}getFile(t){if(this.status!==e.DevbookStatus.Connected)throw new Error("Not connected to the VM yet.");return this.context.getFile({path:t})}writeFile(t,n){if(this.status!==e.DevbookStatus.Connected)throw new Error("Not connected to the VM yet.");return this.context.updateFile({path:t,content:n})}updateStatus(){if(this.isDestroyed)return void(this.status!==e.DevbookStatus.Disconnected&&(this.status=e.DevbookStatus.Disconnected));let t;switch(this.sessionStatus){case m.Disconnected:t=e.DevbookStatus.Disconnected;break;case m.Connecting:t=e.DevbookStatus.Connecting;break;case m.Connected:if(!this.isEnvReady){t=e.DevbookStatus.Connecting;break}t=e.DevbookStatus.Connected}this.status=t}}e.Devbook=U,e.useDevbook=function({env:n,debug:i,port:s}){const[o,r]=t.useState(),[a,h]=t.useState(e.DevbookStatus.Disconnected),[l,d]=t.useState([]),[c,u]=t.useState([]),[g,m]=t.useState(),v=t.useCallback((e=>{o&&(u([]),d([]),o.runCmd(e))}),[o]);return t.useEffect((function(){const e=new U({debug:i,env:n,onStatusChange(e){h(e)},onStderr(e){d((t=>[...t,e]))},onStdout(e){u((t=>[...t,e]))},onURLChange(e){s&&m(e(s))}});return u([]),d([]),m(void 0),r(e),()=>{e.destroy()}}),[n,i,s]),{stderr:l,stdout:c,runCmd:v,status:a,fs:null==o?void 0:o.fs,url:g}},Object.defineProperty(e,"__esModule",{value:!0})}));
//# sourceMappingURL=index.js.map

@@ -9,3 +9,3 @@ import { DevbookStatus, Env, FS } from '../core';

*
* This affects which runtime (NodeJS, etc.,...) will be available and used in the {@link State.runCode} function.
* This affects which runtime (NodeJS, etc.,...) will be available and used in the {@link State.runCmd} function.
*

@@ -30,11 +30,11 @@ * {@link useDevbook} hooks with different environments are isolated - each has their own filesystem and process namespace.

/**
* Stderr from the last code or command run with {@link State.runCode} or {@link State.runCmd}.
* Stderr from the last command run with {@link State.runCmd}.
*
* This array is reset when you call {@link State.runCode} or {@link State.runCmd}.
* This array is reset when you call {@link State.runCmd}.
*/
stderr: string[];
/**
* Stdout from the last code or command run with {@link State.runCode} or {@link State.runCmd}.
* Stdout from the command run with {@link State.runCmd}.
*
* This array is reset when you call {@link State.runCode} or {@link State.runCmd}.
* This array is reset when you call {@link State.runCmd}.
*/

@@ -47,10 +47,2 @@ stdout: string[];

/**
* Run `code` in the VM using the runtime you passed to this {@link useDevbook} hook as the `env`({@link Env}) parameter.
*
* This Devbook's VM shares filesystem and process namespace with other Devbooks that were created by passing the same `env`({@link Env}) to the {@link useDevbook} hooks.
*
* @param code Code to run
*/
runCode: (code: string) => void;
/**
* Run `command` in the VM.

@@ -66,3 +58,3 @@ *

*/
fs: FS;
fs?: FS;
/**

@@ -77,3 +69,3 @@ * URL address that allows you to connect to a port ({@link Opts.port})

*
* This hook exposes functions for running code ({@link State.runCode}) and commands ({@link State.runCmd}) while managing
* This hook exposes functions for running commands ({@link State.runCmd}) while managing
* {@link State.stderr}, {@link State.stdout}, and {@link State.status} - reloading the component when these fields change.

@@ -80,0 +72,0 @@ */

{
"name": "@devbookhq/sdk",
"version": "1.0.9",
"version": "1.0.10",
"description": "Devbook allows visitors of your docs to interact with and execute any code snippet or shell command in a private VM",

@@ -5,0 +5,0 @@ "homepage": "https://usedevbook.com",

@@ -25,3 +25,2 @@ # Devbook SDK

useDevbook,
Env,
DevbookStatus,

@@ -37,16 +36,12 @@ } from '@devbookhq/sdk'

// 3. Use the hook
const { stdout, stderr, status, runCode, url, fs } = useDevbook({ env: Env.NodeJS, port: 3000 })
const { stdout, stderr, status, url, fs, runCmd } = useDevbook({ env: 'nodejs-v16', port: 3000 })
function handleRun() {
// 4. Execute the code
runCode(code)
}
async function handleFS() {
async function handleRun() {
if (status !== DevbookStatus.Connected) return
// 5. Manipulate the filesystem
await dbk.fs.write('/index.js', 'console.log("Hello world!")')
const content = await dbk.fs.get('/index.js')
console.log('Content of the "/index.js" file', content)
if (!fs) return
// 4. Manipulate the filesystem
await fs.write('/index.js', code)
// 5. Execute the code
runCmd(`node ./index.js`)
}

@@ -62,3 +57,2 @@

<button onClick={handleRun}>Run</button>
<button onClick={handleFS}>Test FS</button>
</>

@@ -79,3 +73,3 @@ )}

// 1. Import the class
import { Devbook, Env, DevbookStatus } from '@devbookhq/sdk'
import { Devbook, DevbookStatus } from '@devbookhq/sdk'

@@ -89,3 +83,3 @@ // 2. Define your code

const dbk = new Devbook({
env: Env.NodeJS,
env: 'nodejs-v16',
onStdout(out) {

@@ -106,10 +100,10 @@ console.log('stdout', { err })

if (dbk.status === DevbookStatus.Connected) {
// 4. Execute the code
dbk.runCode(code)
// 5. Manipulate the filesystem
await dbk.fs.write('/index.js', 'console.log("Hello world!")')
if (dbk.status === DevbookStatus.Connected && fs) {
// 4. Manipulate the filesystem
await dbk.fs.write('/index.js', code)
const content = await dbk.fs.get('/index.js')
console.log('Content of the "/index.js" file', content)
// 4. Execute the code
dbk.runCmd('node ./index.js')
}

@@ -116,0 +110,0 @@ ```

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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc