Huge News!Announcing our $40M Series B led by Abstract Ventures.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.12 to 1.0.13

4

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

@@ -26,2 +26,6 @@ export declare enum TRunner {

RunningCmds = "RunningEnvironment.RunningCmds",
TermData = "RunningEnvironment.TermData",
TermResize = "RunningEnvironment.TermResize",
TermStart = "RunningEnvironment.TermStart",
TermStartAck = "RunningEnvironment.TermStartAck",
RunCode = "RunningEnvironment.Run"

@@ -28,0 +32,0 @@ }

2

lib/cjs/common-ts/RunnerWebSocket/index.d.ts
export { TRunner, TRunningEnvironment, TCodeCell, MessageType, } from './BaseMessage';
export type { BaseMessage, } from './BaseMessage';
export type { BaseRunningEnvironment, RunningEnvironment_Start, RunningEnvironment_StartAck, RunningEnvironment_Eval, RunningEnvironment_FSEventCreate, RunningEnvironment_FSEventRemove, RunningEnvironment_FSEventWrite, RunningEnvironment_CreateDir, RunningEnvironment_RemoveFile, RunningEnvironment_ListDir, RunningEnvironment_FileContent, RunningEnvironment_WriteFile, RunningEnvironment_DirContent, RunningEnvironment_GetFile, RunningEnvironment_Stdout, RunningEnvironment_Stderr, RunningEnvironment_ExecCmd, RunningEnvironment_KillCmd, RunningEnvironment_ListRunningCmds, RunningEnvironment_CmdOut, RunningEnvironment_CmdExit, RunningEnvironment_RunningCmds, RunningEnvironment_RunCode, } from './RunningEnvironmentMessage';
export type { BaseRunningEnvironment, RunningEnvironment_Start, RunningEnvironment_StartAck, RunningEnvironment_Eval, RunningEnvironment_FSEventCreate, RunningEnvironment_FSEventRemove, RunningEnvironment_FSEventWrite, RunningEnvironment_CreateDir, RunningEnvironment_RemoveFile, RunningEnvironment_ListDir, RunningEnvironment_FileContent, RunningEnvironment_WriteFile, RunningEnvironment_DirContent, RunningEnvironment_GetFile, RunningEnvironment_Stdout, RunningEnvironment_Stderr, RunningEnvironment_ExecCmd, RunningEnvironment_KillCmd, RunningEnvironment_ListRunningCmds, RunningEnvironment_CmdOut, RunningEnvironment_CmdExit, RunningEnvironment_RunningCmds, RunningEnvironment_RunCode, RunningEnvironment_TermData, RunningEnvironment_TermStart, RunningEnvironment_TermStartAck, RunningEnvironment_TermResize, } from './RunningEnvironmentMessage';
export type { BaseCodeCell, CodeCell_Error, } from './CodeCellMessage';
export type { RunnerError, } from './RunnerErrorMessage';
export { ErrorCodes, ErrorFactory, } from './RunnerErrorMessage';

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

export interface BaseRunningEnvironment extends BaseMessage {
type: TRunningEnvironment.Start | TRunningEnvironment.StartAck | TRunningEnvironment.Eval | TRunningEnvironment.FSEventCreate | TRunningEnvironment.FSEventRemove | TRunningEnvironment.FSEventWrite | TRunningEnvironment.CreateDir | TRunningEnvironment.WriteFile | TRunningEnvironment.RemoveFile | TRunningEnvironment.ListDir | TRunningEnvironment.DirContent | TRunningEnvironment.FileContent | TRunningEnvironment.GetFile | TRunningEnvironment.Stdout | TRunningEnvironment.Stderr | TRunningEnvironment.ExecCmd | TRunningEnvironment.KillCmd | TRunningEnvironment.ListRunningCmds | TRunningEnvironment.CmdOut | TRunningEnvironment.CmdExit | TRunningEnvironment.RunningCmds | TRunningEnvironment.RunCode;
type: TRunningEnvironment.Start | TRunningEnvironment.StartAck | TRunningEnvironment.Eval | TRunningEnvironment.FSEventCreate | TRunningEnvironment.FSEventRemove | TRunningEnvironment.FSEventWrite | TRunningEnvironment.CreateDir | TRunningEnvironment.WriteFile | TRunningEnvironment.RemoveFile | TRunningEnvironment.ListDir | TRunningEnvironment.DirContent | TRunningEnvironment.FileContent | TRunningEnvironment.GetFile | TRunningEnvironment.Stdout | TRunningEnvironment.Stderr | TRunningEnvironment.ExecCmd | TRunningEnvironment.KillCmd | TRunningEnvironment.ListRunningCmds | TRunningEnvironment.CmdOut | TRunningEnvironment.CmdExit | TRunningEnvironment.RunningCmds | TRunningEnvironment.RunCode | TRunningEnvironment.TermData | TRunningEnvironment.TermStart | TRunningEnvironment.TermStartAck | TRunningEnvironment.TermResize;
payload: {

@@ -180,2 +180,35 @@ environmentID: string;

}
export interface RunningEnvironment_TermStart extends BaseRunningEnvironment {
type: TRunningEnvironment.TermStart;
payload: {
environmentID: string;
terminalID?: string;
messageID: string;
};
}
export interface RunningEnvironment_TermStartAck extends BaseRunningEnvironment {
type: TRunningEnvironment.TermStartAck;
payload: {
environmentID: string;
terminalID: string;
messageID: string;
};
}
export interface RunningEnvironment_TermData extends BaseRunningEnvironment {
type: TRunningEnvironment.TermData;
payload: {
environmentID: string;
terminalID: string;
data: string;
};
}
export interface RunningEnvironment_TermResize extends BaseRunningEnvironment {
type: TRunningEnvironment.TermResize;
payload: {
environmentID: string;
terminalID: string;
cols: number;
rows: number;
};
}
/**

@@ -182,0 +215,0 @@ * Received from remote Runner when an environments prints to stdout.

@@ -46,3 +46,19 @@ import { Filesystem } from './runningEnvironment/filesystem';

}
export interface TerminalSession {
sendData: (data: string) => void;
resize: ({ cols, rows }: {
cols: number;
rows: number;
}) => void;
destroy: () => void;
}
/**
* Methods for managing terminal sessions.
*
* This object is used internally by the `Terminal` component from Devbook UI package - https://github.com/devbookhq/ui#terminal.
*/
export interface Terminal {
createSession: (onData: (data: string) => void, activeTerminalID?: string) => Promise<TerminalSession>;
}
/**
* States of a {@link Devbook} connection to a VM.

@@ -75,5 +91,2 @@ */

private executionID;
private _sessionID?;
private get sessionID();
private set sessionID(value);
private _isDestroyed;

@@ -95,6 +108,7 @@ private get isDestroyed();

private get env();
readonly terminal: Terminal;
/**
* Use this for accessing and manipulating this `Devbook`'s VM's filesystem.
*/
get fs(): FS;
readonly fs: FS;
constructor(opts: {

@@ -122,8 +136,2 @@ /**

/**
* This function will be called when the URL for accessing this `Devbook`'s environment changes.
*
* You can assemble URL for any port by using the `getURL` function from the parameter.
*/
onURLChange?: (getURL: (port: number) => string | undefined) => void;
/**
* If this value is true then this `Devbook` will print detailed logs.

@@ -138,10 +146,2 @@ */

/**
* Compose the URL that can be used for connecting to a port on the environment defined in this `Devbook`'s constructor.
*
* @param port Number of the port that the URL should be connecting to.
* @returns URL address that allows you to connect to a specified port on this `Devbook`'s environment
* or `undefined` if this `Devbook` is not yet connected to a VM.
*/
getURL(port: number): string | undefined;
/**
* Run `command` in the VM.

@@ -153,3 +153,3 @@ *

*/
runCmd(command: string): void;
runCmd(command: string): Promise<void>;
/**

@@ -156,0 +156,0 @@ * Disconnect this `Devbook` from the VM.

@@ -14,3 +14,2 @@ import * as rws from '../common-ts/RunnerWebSocket';

status: SessionStatus;
sessionID?: string;
}) => void;

@@ -23,4 +22,7 @@ onEnvChange?: (env: RunningEnvironment) => void;

private get contextID();
private cmdExitSubscribers;
private fsWriteSubscribers;
private fileContentSubscribers;
private termDataSubscribers;
private termStartAckSubscribers;
readonly env: RunningEnvironment;

@@ -54,3 +56,25 @@ private readonly unsubscribeConnHandler;

command: string;
}): Promise<void>;
startTerminal({ terminalID }: {
terminalID?: string;
}): Promise<string>;
resizeTerminal({ terminalID, cols, rows }: {
terminalID: string;
cols: number;
rows: number;
}): void;
sendTerminalData({ terminalID, data }: {
terminalID: string;
data: string;
}): void;
onTerminalData({ terminalID, onData }: {
terminalID: string;
onData: (data: string) => void;
}): () => void;
private subscribeCmdExit;
private unsubscribeCmdExit;
private subscribeTermStartAck;
private unsubscribeTermStartAck;
private subscribeTermData;
private unsubscribeTermData;
private subscribeFileContent;

@@ -63,2 +87,4 @@ private unsubscribeFileContent;

private handleConnectionMessage;
private vmenv_handleTermStartAck;
private vmenv_handleTermData;
private vmenv_handleFSEventCreate;

@@ -65,0 +91,0 @@ private vmenv_handleFSEventRemove;

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

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

@@ -5,3 +5,5 @@ import EvaluationContext, { EvaluationContextOpts } from './evaluationContext';

private logger;
static config: Config;
static config: Config & {
logging?: boolean;
};
private static _obj;

@@ -8,0 +10,0 @@ static get obj(): Runner;

@@ -49,2 +49,18 @@ import { Env } from '../devbook';

}): void;
export { start, execCmd, writeFile, deleteFile, getFile, createDir, listDir, };
declare function termData(conn: WebSocketConnection, { environmentID, terminalID, data, }: {
environmentID: string;
terminalID: string;
data: string;
}): void;
declare function termResize(conn: WebSocketConnection, { environmentID, terminalID, cols, rows, }: {
environmentID: string;
terminalID: string;
cols: number;
rows: number;
}): void;
declare function termStart(conn: WebSocketConnection, { environmentID, terminalID, messageID, }: {
environmentID: string;
terminalID?: string;
messageID: string;
}): void;
export { start, execCmd, writeFile, deleteFile, getFile, createDir, listDir, termStart, termData, termResize, };
import * as rws from '../common-ts/RunnerWebSocket';
export interface Opts {
domain: string;
logging?: boolean;
}
interface Handler {
onMessage: (msg: rws.BaseMessage) => void;
onOpen: (sessionID: string) => void;
onOpen: () => void;
onClose: () => void;

@@ -21,3 +22,3 @@ }

get isConnecting(): boolean | undefined;
constructor({ domain }: Opts);
constructor({ domain, logging }: Opts);
subscribeHandler(handler: Handler): () => void;

@@ -24,0 +25,0 @@ connect(sessionID?: string): void;

export { useDevbook } from './react';
export type { Opts as UseDevbookOpts, } from './react';
export { Devbook, DevbookStatus, } from './core';
export type { Config, Env, } from './core';
export type { Config, Env, Terminal, TerminalSession, FS, } from './core';

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

"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)}}
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var t=require("react");
/*! *****************************************************************************

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

PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */function n(t,e,n,i){return new(n||(n=Promise))((function(s,o){function r(t){try{h(i.next(t))}catch(t){o(t)}}function a(t){try{h(i.throw(t))}catch(t){o(t)}}function h(t){var e;t.done?s(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(r,a)}h((i=i.apply(t,e||[])).next())}))}function i(t){return new Promise((e=>setTimeout(e,t)))}var s,o,r;!function(t){t.Error="Runner.Error"}(s||(s={})),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:s,RunningEnvironment:o,CodeCell:r};class h{constructor({domain:t}){this.logger=new e("WebSocketConnection"),this.handlers=[],this.url=`wss://${t}`}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 2.5s"),yield i(2500),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,c;!function(t){t.Ok="Ok",t.Terminated="Terminated"}(l||(l={}));class d{constructor({id:t,url:n}){this.logger=new e("RunnerSession"),this.lastPing=new Date,this.id=t,this.url=n}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"}(c||(c={}));class u{constructor({conn:t,domain:n}){this.logger=new e("SessionManager"),this.userActivity=Promise.resolve(),this.isGettingSessionActive=!1,this.status=c.Disconnected,this.conn=t,this.url=`https://${n}`,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))}stop(){var t;null===(t=this.startActivity)||void 0===t||t.call(this),this.userActivity=new Promise((t=>{this.startActivity=t})),this.reset()}start(){var t;null===(t=this.startActivity)||void 0===t||t.call(this)}reset(){this.logger.log("Reset"),this.status=c.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=c.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),s=yield n.json();if(!n.ok){this.logger.error("Non-OK response when trying to ping active Runner session. Will try again in 2.5s",n.headers,s),yield i(2500);continue}for(this.session=new d({id:s.sessionID,url:this.url}),this.logger.log(`Acquired session "${this.session.id}"`),this.cachedSessionID=this.session.id,this.status=c.Connected,this.conn.connect(this.session.id),this.logger.log(`Started pinging session "${this.session.id}"`);this.session;)try{yield this.userActivity,yield this.session.ping(),yield i(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=c.Disconnected,this.conn.close()}catch(t){this.logger.error("Failed to acquire Runner session. Will try again in 2.5s",t),yield i(2500)}}}))}}function g(t,e){for(var n=0,i=t.length-1;i>=0;i--){var s=t[i];"."===s?t.splice(i,1):".."===s?(t.splice(i,1),n++):n&&(t.splice(i,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 i=n>=0?arguments[n]:"/";if("string"!=typeof i)throw new TypeError("Arguments to path.resolve must be strings");i&&(t=i+"/"+t,e="/"===i.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],i=e[1];return n||i?(i&&(i=i.substr(0,i.length-1)),n+i):"."},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 i=n(t.split("/")),s=n(e.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 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=[],i=0;i<t.length;i++)e(t[i],i,t)&&n.push(t[i]);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 i=this.children.map((i=>i.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(i)}}}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:i}){super(),this.name="name-prompt",this.parent=t,this.forNode=e,this.path=y.join(t.path,this.name),this.onConfirm=n,this.onBlur=i}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 _ extends w{constructor({onAddItem:t}){super(),this.name="/",this.path="/",this.parent=void 0,this.children=[],this.addItemHandler=t}serialize(t,e,n){const i=this.children.map((i=>i.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(i)}}}class F 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 x{constructor(){this.logger=new e("Filesystem"),this.root=new _({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 _||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 i;i="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 F?n.children=[i]:n.children.push(i),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 _||n instanceof I))throw new Error(`Node at '${t}' is not a directory or root node`);const i=n.children.length;n.children=n.children.filter((t=>t.name!==e.name));i!==n.children.length?(0===n.children.length&&(n.children=[new F({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 _||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 i of e.content){let e;e="Dir"===i.type?new I({name:i.name,parent:t,onAddItem:({event:t,dir:e,type:n})=>this.showPrompt({event:t,parent:e,type:n})}):new R({name:i.name,parent:t}),n.push(e)}t.children=n}else t.children=[new F({parent:t})];n&&t.children.push(n)}this.notifyOnDirsChangeLs({dirPaths:t.map((t=>t.dirPath))})}showPrompt(t){const{event:e,parent:n,type:i}=t;if(this.logger.log("Show prompt",{parent:n,type:i}),n.children.some((t=>t instanceof k)))return;e.preventDefault();const s=new k({parent:n,forNode:i,onConfirm:((t,e)=>{if(this.logger.log("Prompt confirm",{prompt:t,name:e}),!e)return;const n=t.parent.path,s=y.join(t.parent.path,e);this.removeFromParent(t),this.notifyOnDirsChangeLs({dirPaths:[n]}),this.notifyOnNewItemConfirmLs({fullPath:s,name:e,type:i})}).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(s),this.notifyOnDirsChangeLs({dirPaths:[s.parent.path]}),this.notifyOnShowPromptLs({dirPath:s.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 i of t.children)i instanceof I?this.print(i,e+1):console.log(n+" "+i.path,`(${i.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 _||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 _||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,i="/";for(const t of e)if(i=y.join(i,t),!this.find(i)){const e=y.dirname(i);n=this.mkDir({parentPath:e,name:t})}return n}removeFromParent(t){const{parent:e}=t;(e instanceof _||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 P(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 L{constructor(t,e){this.contextID=t,this.templateID=e,this.output=[],this.filesystem=new x,this.isReady=!1,this.id=`${t}_${P(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 i={type:a.RunningEnvironment.Start,payload:{environmentID:e,templateID:n}};t.send(i)}class N{constructor(t){var n,i;this.opts=t,this.fsWriteSubscribers=[],this.fileContentSubscribers=[],this.logger=new e(`EvaluationContext [${t.templateID}]`,t.debug),this.env=new L(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===(i=(n=this.opts).onEnvChange)||void 0===i||i.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)})),i=n=>{n.path.endsWith(t)&&e(n.content)};this.subscribeFileContent(i),function(t,{environmentID:e,path:n}){const i={type:a.RunningEnvironment.GetFile,payload:{environmentID:e,path:n}};t.send(i)}(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(i)}}))}deleteFile({path:t}){this.logger.log("Delete file",{filepath:t}),function(t,{environmentID:e,path:n}){const i={type:a.RunningEnvironment.RemoveFile,payload:{environmentID:e,path:n}};t.send(i)}(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 i=new Promise(((t,e)=>{n=t,setTimeout((()=>{e("Timeout")}),1e4)})),s=e=>{e.path.endsWith(t)&&n()};this.subscribeFSWrite(s),function(t,{environmentID:e,path:n,content:i}){const s={type:a.RunningEnvironment.WriteFile,payload:{environmentID:e,path:n,content:i}};t.send(s)}(this.opts.conn,{environmentID:this.env.id,path:t,content:e});try{yield i}catch(e){throw new Error(`File ${t} not written to VM: ${e}`)}finally{this.unsubscribeFSWrite(s)}}))}createDir({path:t}){this.logger.log("Create dir",{filepath:t}),function(t,{environmentID:e,path:n}){const i={type:a.RunningEnvironment.CreateDir,payload:{environmentID:e,path:n}};t.send(i)}(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 i={type:a.RunningEnvironment.ListDir,payload:{environmentID:e,path:n}};t.send(i)}(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:i}){const s={type:a.RunningEnvironment.ExecCmd,payload:{environmentID:e,executionID:n,command:i}};t.send(s)}(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:c.Connecting})}handleConnectionClose(){var t,e;null===(e=(t=this.opts).onSessionChange)||void 0===e||e.call(t,{status:c.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),i="Directory"===t.type?"Dir":"File";this.env.filesystem.addNodeToDir(n,{name:e,type:i})}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),i="Directory"===n.type?"Dir":"File";e.push({name:t,type:i})}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,i,s;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),null===(s=(i=this.opts).onSessionChange)||void 0===s||s.call(i,{status:c.Connected,sessionID:this.opts.conn.sessionID})}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 A{constructor(){this.logger=new e("Runner"),this.conn=new h({domain:A.config.domain}),this.sessManager=new u({conn:this.conn,domain:A.config.domain})}static get obj(){if(!A.config)throw new Error("Config not set");return A._obj||(A._obj=new A)}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}))}__internal__start(){this.sessManager.start()}__internal__stop(){this.sessManager.stop()}__debug__loadNewSession(){this.logger.log("__debug__loadNewSession"),this.sessManager.reset()}}const $=(M="1234567890abcdefghijklmnopqrstuvwxyz",j=6,()=>{let t="",e=j;for(;e--;)t+=M[Math.random()*M.length|0];return t});var M,j,W;exports.DevbookStatus=void 0,(W=exports.DevbookStatus||(exports.DevbookStatus={})).Disconnected="Disconnected",W.Connecting="Connecting",W.Connected="Connected";class H{constructor(t){if(this.opts=t,this.contextID="default",this.executionID=$(),this._isDestroyed=!1,this._isEnvReady=!1,this._sessionStatus=c.Disconnected,this._status=exports.DevbookStatus.Disconnected,!t.config)throw new Error("Missing Devbook config");const e=this.getURL.bind(this),n=()=>this.opts.env,i=()=>this.executionID,s=t=>this.isEnvReady=t,o=t=>this.sessionStatus=t,r=t=>this.sessionID=t;A.config=this.opts.config,this.context=A.obj.createContext({debug:t.debug,templateID:t.env,contextID:this.contextID,onEnvChange(i){var o;i.templateID===n()&&(s(i.isReady),null===(o=t.onURLChange)||void 0===o||o.call(t,e))},onSessionChange({status:n,sessionID:i}){var s;r(i),o(n),null===(s=t.onURLChange)||void 0===s||s.call(t,e)},onCmdOut(e){var n,s;e.executionID===i()&&(void 0!==e.stdout&&(null===(n=t.onStdout)||void 0===n||n.call(t,e.stdout)),void 0!==e.stderr&&(null===(s=t.onStderr)||void 0===s||s.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=$(),this.context.executeCommand({executionID:this.executionID,command:t})}destroy(){this.context.destroy(),this.isDestroyed=!0}__internal__start(){A.obj.__internal__start()}__internal__stop(){A.obj.__internal__stop()}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 c.Disconnected:t=exports.DevbookStatus.Disconnected;break;case c.Connecting:t=exports.DevbookStatus.Connecting;break;case c.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,config:i}){const[s,o]=t.useState(),[r,a]=t.useState(exports.DevbookStatus.Disconnected),[h,l]=t.useState([]),[c,d]=t.useState([]),u=t.useCallback((t=>{s&&(d([]),l([]),s.runCmd(t))}),[s]);return t.useEffect((function(){const t=new H({debug:n,env:e,onStatusChange(t){a(t)},onStderr(t){l((e=>[...e,t]))},onStdout(t){d((e=>[...e,t]))},config:i});return d([]),l([]),o(t),()=>{t.destroy()}}),[e,n,i]),{stderr:h,stdout:c,runCmd:u,status:r,fs:null==s?void 0:s.fs}};
***************************************************************************** */function e(t,e,n,i){return new(n||(n=Promise))((function(s,o){function r(t){try{h(i.next(t))}catch(t){o(t)}}function a(t){try{h(i.throw(t))}catch(t){o(t)}}function h(t){var e;t.done?s(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(r,a)}h((i=i.apply(t,e||[])).next())}))}function n(t){return e="1234567890abcdefghijklmnopqrstuvwxyz",n=t,()=>{let t="",i=n;for(;i--;)t+=e[Math.random()*e.length|0];return t};var e,n}class i{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)}}function s(t){return new Promise((e=>setTimeout(e,t)))}var o,r,a;!function(t){t.Error="Runner.Error"}(o||(o={})),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.TermData="RunningEnvironment.TermData",t.TermResize="RunningEnvironment.TermResize",t.TermStart="RunningEnvironment.TermStart",t.TermStartAck="RunningEnvironment.TermStartAck",t.RunCode="RunningEnvironment.Run"}(r||(r={})),function(t){t.Error="CodeCell.Error"}(a||(a={}));const h={Runner:o,RunningEnvironment:r,CodeCell:a};class l{constructor({domain:t,logging:e}){this.handlers=[],this.url=`wss://${t}`,this.logger=new i("WebSocketConnection",e)}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.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(){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()))}_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 e(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 2.5s"),yield s(2500),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(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((t=>t.onMessage(n)))):this.logger.error("Runner error",n):this.logger.error('Message "type" field has unexpected value',n)}}var c,d;!function(t){t.Ok="Ok",t.Terminated="Terminated"}(c||(c={}));class u{constructor({id:t,url:e}){this.logger=new i("RunnerSession"),this.lastPing=new Date,this.id=t,this.url=e}ping(){return e(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===c.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 m{constructor({conn:t,domain:e}){this.logger=new i("SessionManager"),this.userActivity=Promise.resolve(),this.isGettingSessionActive=!1,this.status=d.Disconnected,this.conn=t,this.url=`https://${e}`,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))}stop(){var t;null===(t=this.startActivity)||void 0===t||t.call(this),this.userActivity=new Promise((t=>{this.startActivity=t})),this.reset()}start(){var t;null===(t=this.startActivity)||void 0===t||t.call(this)}reset(){this.logger.log("Reset"),this.status=d.Disconnected,this.cachedSessionID=null,this.conn.close(),this.session=void 0}getSession(){var t;return e(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 2.5s",n.headers,i),yield s(2500);continue}for(this.session=new u({id:i.sessionID,url:this.url}),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.userActivity,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 2.5s",t),yield s(2500)}}}))}}function g(t,e){for(var n=0,i=t.length-1;i>=0;i--){var s=t[i];"."===s?t.splice(i,1):".."===s?(t.splice(i,1),n++):n&&(t.splice(i,1),n--)}if(e)for(;n--;n)t.unshift("..");return t}var v=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/,p=function(t){return v.exec(t).slice(1)};function f(){for(var t="",e=!1,n=arguments.length-1;n>=-1&&!e;n--){var i=n>=0?arguments[n]:"/";if("string"!=typeof i)throw new TypeError("Arguments to path.resolve must be strings");i&&(t=i+"/"+t,e="/"===i.charAt(0))}return(e?"/":"")+(t=g(S(t.split("/"),(function(t){return!!t})),!e).join("/"))||"."}function D(t){var e=y(t),n="/"===E(t,-1);return(t=g(S(t.split("/"),(function(t){return!!t})),!e).join("/"))||e||(t="."),t&&n&&(t+="/"),(e?"/":"")+t}function y(t){return"/"===t.charAt(0)}var b={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],i=e[1];return n||i?(i&&(i=i.substr(0,i.length-1)),n+i):"."},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=f(t).substr(1),e=f(e).substr(1);for(var i=n(t.split("/")),s=n(e.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 t=Array.prototype.slice.call(arguments,0);return D(S(t,(function(t,e){if("string"!=typeof t)throw new TypeError("Arguments to path.join must be strings");return t})).join("/"))},isAbsolute:y,normalize:D,resolve:f};function S(t,e){if(t.filter)return t.filter(e);for(var n=[],i=0;i<t.length;i++)e(t[i],i,t)&&n.push(t[i]);return n}var C,E="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 b.normalize(this.path).split(b.sep).length-1}}function I(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 R extends w{constructor({name:t,parent:e,onAddItem:n}){super(),this.children=[],this.name=t,this.parent=e,this.addItemHandler=n,this.path=b.join(this.parent.path,this.name)}removeChildNode(t){this.children=this.children.filter((e=>e!==t))}serialize(t,e,n){const i=this.children.map((i=>i.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:I(i)}}}class k extends w{constructor({name:t,parent:e}){super(),this.name=t,this.parent=e,this.path=b.join(this.parent.path,this.name)}serialize(){return{type:"File",key:this.path,title:this.name,isLeaf:!0}}}class x extends w{constructor({parent:t,forNode:e,onConfirm:n,onBlur:i}){super(),this.name="name-prompt",this.parent=t,this.forNode=e,this.path=b.join(t.path,this.name),this.onConfirm=n,this.onBlur=i}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 _ extends w{constructor({onAddItem:t}){super(),this.name="/",this.path="/",this.parent=void 0,this.children=[],this.addItemHandler=t}serialize(t,e,n){const i=this.children.map((i=>i.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:I(i)}}}class F extends w{constructor({parent:t}){super(),this.name="empty-node",this.parent=t,this.path=b.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 i("Filesystem"),this.root=new _({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 _||n instanceof R))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 i;i="Dir"===e.type?new R({name:e.name,parent:n,onAddItem:({event:t,dir:e,type:n})=>this.showPrompt({event:t,parent:e,type:n})}):new k({name:e.name,parent:n}),1===n.children.length&&n.children[0]instanceof F?n.children=[i]:n.children.push(i),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 _||n instanceof R))throw new Error(`Node at '${t}' is not a directory or root node`);const i=n.children.length;n.children=n.children.filter((t=>t.name!==e.name));i!==n.children.length?(0===n.children.length&&(n.children=[new F({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 _||t instanceof R))throw new Error(`Node at '${e.dirPath}' is not a directory or a root node`);const n=t.children.find((t=>t instanceof x));if(e.content.length){const n=[];for(const i of e.content){let e;e="Dir"===i.type?new R({name:i.name,parent:t,onAddItem:({event:t,dir:e,type:n})=>this.showPrompt({event:t,parent:e,type:n})}):new k({name:i.name,parent:t}),n.push(e)}t.children=n}else t.children=[new F({parent:t})];n&&t.children.push(n)}this.notifyOnDirsChangeLs({dirPaths:t.map((t=>t.dirPath))})}showPrompt(t){const{event:e,parent:n,type:i}=t;if(this.logger.log("Show prompt",{parent:n,type:i}),n.children.some((t=>t instanceof x)))return;e.preventDefault();const s=new x({parent:n,forNode:i,onConfirm:((t,e)=>{if(this.logger.log("Prompt confirm",{prompt:t,name:e}),!e)return;const n=t.parent.path,s=b.join(t.parent.path,e);this.removeFromParent(t),this.notifyOnDirsChangeLs({dirPaths:[n]}),this.notifyOnNewItemConfirmLs({fullPath:s,name:e,type:i})}).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(s),this.notifyOnDirsChangeLs({dirPaths:[s.parent.path]}),this.notifyOnShowPromptLs({dirPath:s.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 i of t.children)i instanceof R?this.print(i,e+1):console.log(n+" "+i.path,`(${i.name})`)}find(t,e=this.root){if(this.logger.log("Find (recursion)",{currentPath:e.path,targetPath:t}),t=b.normalize(t),e.path===t)return e;const n=t.split(b.sep).length-1;if(!(e.level>n)&&(e instanceof _||e instanceof R))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 _||e instanceof R))throw new Error("Parent is not a dir or root");const n=new R({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(b.sep);let n,i="/";for(const t of e)if(i=b.join(i,t),!this.find(i)){const e=b.dirname(i);n=this.mkDir({parentPath:e,name:t})}return n}removeFromParent(t){const{parent:e}=t;(e instanceof _||e instanceof R)&&(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 O(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"}(C||(C={}));class A{constructor(t,e){this.contextID=t,this.templateID=e,this.output=[],this.filesystem=new P,this.isReady=!1,this.id=`${t}_${O(e)}`}restart(){this.output=[],this.isReady=!1,this.filesystem.setDirsContent([{dirPath:"/",content:[]}])}logOutput(t,e){this.output=[...this.output,{message:t,source:e}]}}function T(t,{environmentID:e,templateID:n}){const i={type:h.RunningEnvironment.Start,payload:{environmentID:e,templateID:n}};t.send(i)}const N=n(6);class L{constructor(t){var e,n;this.opts=t,this.cmdExitSubscribers=[],this.fsWriteSubscribers=[],this.fileContentSubscribers=[],this.termDataSubscribers=[],this.termStartAckSubscribers=[],this.logger=new i(`EvaluationContext [${t.templateID}]`,t.debug),this.env=new A(this.contextID,t.templateID);this.unsubscribeConnHandler=this.opts.conn.subscribeHandler({onOpen:()=>this.handleConnectionOpen(),onMessage:t=>this.handleConnectionMessage(t),onClose:()=>this.handleConnectionClose()}),this.opts.conn.isOpen&&this.handleConnectionOpen(),this.opts.conn.isClosed&&this.handleConnectionClose(),T(this.opts.conn,{environmentID:this.env.id,templateID:this.env.templateID}),null===(n=(e=this.opts).onEnvChange)||void 0===n||n.call(e,this.env)}get contextID(){return this.opts.contextID}restart(){this.logger.log("Restart",this.opts.conn.sessionID),this.env.restart(),T(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 e(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)})),i=n=>{n.path.endsWith(t)&&e(n.content)};this.subscribeFileContent(i),function(t,{environmentID:e,path:n}){const i={type:h.RunningEnvironment.GetFile,payload:{environmentID:e,path:n}};t.send(i)}(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(i)}}))}deleteFile({path:t}){this.logger.log("Delete file",{filepath:t}),function(t,{environmentID:e,path:n}){const i={type:h.RunningEnvironment.RemoveFile,payload:{environmentID:e,path:n}};t.send(i)}(this.opts.conn,{environmentID:this.env.id,path:t})}updateFile({path:t,content:n}){return e(this,void 0,void 0,(function*(){let e;this.logger.log("Update file",{filepath:t});const i=new Promise(((t,n)=>{e=t,setTimeout((()=>{n("Timeout")}),1e4)})),s=n=>{n.path.endsWith(t)&&e()};this.subscribeFSWrite(s),function(t,{environmentID:e,path:n,content:i}){const s={type:h.RunningEnvironment.WriteFile,payload:{environmentID:e,path:n,content:i}};t.send(s)}(this.opts.conn,{environmentID:this.env.id,path:t,content:n});try{yield i}catch(e){throw new Error(`File ${t} not written to VM: ${e}`)}finally{this.unsubscribeFSWrite(s)}}))}createDir({path:t}){this.logger.log("Create dir",{filepath:t}),function(t,{environmentID:e,path:n}){const i={type:h.RunningEnvironment.CreateDir,payload:{environmentID:e,path:n}};t.send(i)}(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 i={type:h.RunningEnvironment.ListDir,payload:{environmentID:e,path:n}};t.send(i)}(this.opts.conn,{environmentID:this.env.id,path:t})}executeCommand({executionID:t,command:n}){return e(this,void 0,void 0,(function*(){let e;this.logger.log("Execute shell command",{executionID:t,command:n});let i=!1;const s=new Promise(((t,n)=>{e=t,setTimeout((()=>{i||n("Timeout")}),1e4)})),o=n=>{n.executionID===t&&(e(t),i=!0)};this.subscribeCmdExit(o),function(t,{environmentID:e,executionID:n,command:i}){const s={type:h.RunningEnvironment.ExecCmd,payload:{environmentID:e,executionID:n,command:i}};t.send(s)}(this.opts.conn,{environmentID:this.env.id,executionID:t,command:n});try{yield s}catch(t){throw new Error(`Can't exit cmd: ${t}`)}finally{this.unsubscribeCmdExit(o)}}))}startTerminal({terminalID:t}){return e(this,void 0,void 0,(function*(){this.logger.log("Start terminal",{terminalID:t});const e=N();let n,i=!1;const s=new Promise(((t,e)=>{n=t,setTimeout((()=>{i||e("Timeout")}),1e4)})),o=t=>{t.messageID===e&&(n(t.terminalID),i=!0)};this.subscribeTermStartAck(o),function(t,{environmentID:e,terminalID:n,messageID:i}){const s={type:h.RunningEnvironment.TermStart,payload:{environmentID:e,terminalID:n,messageID:i}};t.send(s)}(this.opts.conn,{environmentID:this.env.id,terminalID:t,messageID:e});try{return yield s}catch(t){throw new Error(`Can't start terminal session: ${t}`)}finally{this.unsubscribeTermStartAck(o)}}))}resizeTerminal({terminalID:t,cols:e,rows:n}){this.logger.log("Resize terminal",{terminalID:t,cols:e,rows:n}),function(t,{environmentID:e,terminalID:n,cols:i,rows:s}){const o={type:h.RunningEnvironment.TermResize,payload:{environmentID:e,terminalID:n,cols:i,rows:s}};t.send(o)}(this.opts.conn,{environmentID:this.env.id,terminalID:t,cols:e,rows:n})}sendTerminalData({terminalID:t,data:e}){this.logger.log("Send terminal data",{terminalID:t}),function(t,{environmentID:e,terminalID:n,data:i}){const s={type:h.RunningEnvironment.TermData,payload:{environmentID:e,terminalID:n,data:i}};t.send(s)}(this.opts.conn,{environmentID:this.env.id,terminalID:t,data:e})}onTerminalData({terminalID:t,onData:e}){const n=n=>{n.terminalID===t&&e(n.data)};return this.subscribeTermData(n),()=>this.unsubscribeTermData(n)}subscribeCmdExit(t){this.cmdExitSubscribers.push(t)}unsubscribeCmdExit(t){const e=this.cmdExitSubscribers.indexOf(t);e>-1&&this.cmdExitSubscribers.splice(e,1)}subscribeTermStartAck(t){this.termStartAckSubscribers.push(t)}unsubscribeTermStartAck(t){const e=this.termStartAckSubscribers.indexOf(t);e>-1&&this.termStartAckSubscribers.splice(e,1)}subscribeTermData(t){this.termDataSubscribers.push(t)}unsubscribeTermData(t){const e=this.termDataSubscribers.indexOf(t);e>-1&&this.termDataSubscribers.splice(e,1)}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(){var t,e;this.restart(),null===(e=(t=this.opts).onSessionChange)||void 0===e||e.call(t,{status:d.Connecting})}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 h.RunningEnvironment.StartAck:{const e=t;this.vmenv_handleStartAck(e.payload);break}case h.RunningEnvironment.CmdOut:{const e=t;this.vmenv_handleCmdOut(e.payload);break}case h.RunningEnvironment.CmdExit:{const e=t;this.vmenv_handleCmdExit(e.payload);break}case h.RunningEnvironment.FSEventWrite:{const e=t;this.vmenv_handleFSEventWrite(e.payload);break}case h.RunningEnvironment.FileContent:{const e=t;this.vmenv_handleFileContent(e.payload);break}case h.RunningEnvironment.FSEventCreate:{const e=t;this.vmenv_handleFSEventCreate(e.payload);break}case h.RunningEnvironment.FSEventRemove:{const e=t;this.vmenv_handleFSEventRemove(e.payload);break}case h.RunningEnvironment.DirContent:{const e=t;this.vmenv_handleDirContent(e.payload);break}case h.RunningEnvironment.Stderr:{const e=t;this.vmenv_handleStderr(e.payload);break}case h.RunningEnvironment.Stdout:{const e=t;this.vmenv_handleStdout(e.payload);break}case h.RunningEnvironment.TermData:{const e=t;this.vmenv_handleTermData(e.payload);break}case h.RunningEnvironment.TermStartAck:{const e=t;this.vmenv_handleTermStartAck(e.payload);break}default:this.logger.warn("Unknown message type",{message:t})}}vmenv_handleTermStartAck(t){this.logger.log('[vmenv] Handling "TermStartAck"',t),this.termStartAckSubscribers.forEach((e=>e(t)))}vmenv_handleTermData(t){this.logger.log('[vmenv] Handling "TermData"',t),this.termDataSubscribers.forEach((e=>e(t)))}vmenv_handleFSEventCreate(t){this.logger.log('[vmenv] Handling "FSEventCreate"',t);const e=b.basename(t.path),n=b.dirname(t.path),i="Directory"===t.type?"Dir":"File";this.env.filesystem.addNodeToDir(n,{name:e,type:i})}vmenv_handleFSEventRemove(t){this.logger.log('[vmenv] Handling "FSEventRemove"',{payload:t});const e=b.basename(t.path),n=b.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=b.basename(n.path),i="Directory"===n.type?"Dir":"File";e.push({name:t,type:i})}this.env.filesystem.setDirsContent([{dirPath:t.dirPath,content:e}])}vmenv_handleCmdExit(t){var e,n;this.logger.log('[vmenv] Handling "CmdExit"',t),this.cmdExitSubscribers.forEach((e=>e(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,i,s;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),null===(s=(i=this.opts).onSessionChange)||void 0===s||s.call(i,{status:d.Connected})}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,C.Stderr)}vmenv_handleStdout(t){this.logger.log('[vmenv] Handling "Stdout"',t),this.env.logOutput(t.message,C.Stdout)}}class ${constructor(){this.logger=new i("Runner"),this.conn=new l({domain:$.config.domain,logging:$.config.logging}),this.sessManager=new m({conn:this.conn,domain:$.config.domain})}static get obj(){if(!$.config)throw new Error("Config not set");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 L(Object.assign(Object.assign({},t),{conn:this.conn}))}__internal__start(){this.sessManager.start()}__internal__stop(){this.sessManager.stop()}__debug__loadNewSession(){this.logger.log("__debug__loadNewSession"),this.sessManager.reset()}}const M=n(6);var j;exports.DevbookStatus=void 0,(j=exports.DevbookStatus||(exports.DevbookStatus={})).Disconnected="Disconnected",j.Connecting="Connecting",j.Connected="Connected";class W{constructor(t){if(this.opts=t,this.contextID="default",this.executionID=M(),this._isDestroyed=!1,this._isEnvReady=!1,this._sessionStatus=d.Disconnected,this._status=exports.DevbookStatus.Disconnected,!t.config)throw new Error("Missing Devbook config");const n=()=>this.opts.env,i=()=>this.executionID,s=t=>this.isEnvReady=t,o=t=>this.sessionStatus=t;$.config=Object.assign(Object.assign({},this.opts.config),{logging:t.debug}),this.context=$.obj.createContext({debug:t.debug,templateID:t.env,contextID:this.contextID,onEnvChange(t){t.templateID===n()&&s(t.isReady)},onSessionChange({status:t}){o(t)},onCmdOut(e){var n,s;e.executionID===i()&&(void 0!==e.stdout&&(null===(n=t.onStdout)||void 0===n||n.call(t,e.stdout)),void 0!==e.stderr&&(null===(s=t.onStderr)||void 0===s||s.call(t,e.stderr)))}}),this.fs={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:this.env.filesystem.addListener.bind(this.env.filesystem),removeListener:this.env.filesystem.removeListener.bind(this.env.filesystem),serialize:this.env.filesystem.serialize.bind(this.env.filesystem)},this.terminal={createSession:(t,n)=>e(this,void 0,void 0,(function*(){const e=yield this.context.startTerminal({terminalID:n}),i=this.context.onTerminalData({onData:t,terminalID:e});return{destroy:()=>{i()},sendData:t=>{this.context.sendTerminalData({terminalID:e,data:t})},resize:({cols:t,rows:n})=>{this.context.resizeTerminal({terminalID:e,cols:t,rows:n})}}}))}}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}runCmd(t){if(this.status!==exports.DevbookStatus.Connected)throw new Error("Not connected to the VM yet.");return this.executionID=M(),this.context.executeCommand({executionID:this.executionID,command:t})}destroy(){this.context.destroy(),this.isDestroyed=!0}__internal__start(){$.obj.__internal__start()}__internal__stop(){$.obj.__internal__stop()}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=W,exports.useDevbook=function({env:n,debug:i,config:s}){const[o,r]=t.useState(),[a,h]=t.useState(exports.DevbookStatus.Disconnected),[l,c]=t.useState([]),[d,u]=t.useState([]),m=t.useCallback((t=>e(this,void 0,void 0,(function*(){o&&(u([]),c([]),o.runCmd(t))}))),[o]);return t.useEffect((function(){const t=new W({debug:i,env:n,config:{domain:s.domain},onStatusChange(t){h(t)},onStderr(t){c((e=>[...e,t]))},onStdout(t){u((e=>[...e,t]))}});return u([]),c([]),r(t),()=>{t.destroy()}}),[n,i,s.domain]),{stderr:l,stdout:d,runCmd:m,status:a,fs:null==o?void 0:o.fs,terminal:null==o?void 0:o.terminal}};
//# sourceMappingURL=index.js.map

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

import { DevbookStatus, Env, FS, Config } from '../core';
import { DevbookStatus, Env, FS, Terminal, Config } from '../core';
/**

@@ -50,3 +50,3 @@ * Options passed to the {@link useDevbook} hook.

*/
runCmd: (command: string) => void;
runCmd: (command: string) => Promise<void>;
/**

@@ -56,2 +56,8 @@ * Use this for accessing and manipulating this Devbook's VM's filesystem.

fs?: FS;
/**
* Use this for managing terminal sessions.
*
* This object is used internally by the `Terminal` component from Devbook UI package - https://github.com/devbookhq/ui#terminal.
*/
terminal?: Terminal;
}

@@ -58,0 +64,0 @@ /**

@@ -26,2 +26,6 @@ export declare enum TRunner {

RunningCmds = "RunningEnvironment.RunningCmds",
TermData = "RunningEnvironment.TermData",
TermResize = "RunningEnvironment.TermResize",
TermStart = "RunningEnvironment.TermStart",
TermStartAck = "RunningEnvironment.TermStartAck",
RunCode = "RunningEnvironment.Run"

@@ -28,0 +32,0 @@ }

export { TRunner, TRunningEnvironment, TCodeCell, MessageType, } from './BaseMessage';
export type { BaseMessage, } from './BaseMessage';
export type { BaseRunningEnvironment, RunningEnvironment_Start, RunningEnvironment_StartAck, RunningEnvironment_Eval, RunningEnvironment_FSEventCreate, RunningEnvironment_FSEventRemove, RunningEnvironment_FSEventWrite, RunningEnvironment_CreateDir, RunningEnvironment_RemoveFile, RunningEnvironment_ListDir, RunningEnvironment_FileContent, RunningEnvironment_WriteFile, RunningEnvironment_DirContent, RunningEnvironment_GetFile, RunningEnvironment_Stdout, RunningEnvironment_Stderr, RunningEnvironment_ExecCmd, RunningEnvironment_KillCmd, RunningEnvironment_ListRunningCmds, RunningEnvironment_CmdOut, RunningEnvironment_CmdExit, RunningEnvironment_RunningCmds, RunningEnvironment_RunCode, } from './RunningEnvironmentMessage';
export type { BaseRunningEnvironment, RunningEnvironment_Start, RunningEnvironment_StartAck, RunningEnvironment_Eval, RunningEnvironment_FSEventCreate, RunningEnvironment_FSEventRemove, RunningEnvironment_FSEventWrite, RunningEnvironment_CreateDir, RunningEnvironment_RemoveFile, RunningEnvironment_ListDir, RunningEnvironment_FileContent, RunningEnvironment_WriteFile, RunningEnvironment_DirContent, RunningEnvironment_GetFile, RunningEnvironment_Stdout, RunningEnvironment_Stderr, RunningEnvironment_ExecCmd, RunningEnvironment_KillCmd, RunningEnvironment_ListRunningCmds, RunningEnvironment_CmdOut, RunningEnvironment_CmdExit, RunningEnvironment_RunningCmds, RunningEnvironment_RunCode, RunningEnvironment_TermData, RunningEnvironment_TermStart, RunningEnvironment_TermStartAck, RunningEnvironment_TermResize, } from './RunningEnvironmentMessage';
export type { BaseCodeCell, CodeCell_Error, } from './CodeCellMessage';
export type { RunnerError, } from './RunnerErrorMessage';
export { ErrorCodes, ErrorFactory, } from './RunnerErrorMessage';

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

export interface BaseRunningEnvironment extends BaseMessage {
type: TRunningEnvironment.Start | TRunningEnvironment.StartAck | TRunningEnvironment.Eval | TRunningEnvironment.FSEventCreate | TRunningEnvironment.FSEventRemove | TRunningEnvironment.FSEventWrite | TRunningEnvironment.CreateDir | TRunningEnvironment.WriteFile | TRunningEnvironment.RemoveFile | TRunningEnvironment.ListDir | TRunningEnvironment.DirContent | TRunningEnvironment.FileContent | TRunningEnvironment.GetFile | TRunningEnvironment.Stdout | TRunningEnvironment.Stderr | TRunningEnvironment.ExecCmd | TRunningEnvironment.KillCmd | TRunningEnvironment.ListRunningCmds | TRunningEnvironment.CmdOut | TRunningEnvironment.CmdExit | TRunningEnvironment.RunningCmds | TRunningEnvironment.RunCode;
type: TRunningEnvironment.Start | TRunningEnvironment.StartAck | TRunningEnvironment.Eval | TRunningEnvironment.FSEventCreate | TRunningEnvironment.FSEventRemove | TRunningEnvironment.FSEventWrite | TRunningEnvironment.CreateDir | TRunningEnvironment.WriteFile | TRunningEnvironment.RemoveFile | TRunningEnvironment.ListDir | TRunningEnvironment.DirContent | TRunningEnvironment.FileContent | TRunningEnvironment.GetFile | TRunningEnvironment.Stdout | TRunningEnvironment.Stderr | TRunningEnvironment.ExecCmd | TRunningEnvironment.KillCmd | TRunningEnvironment.ListRunningCmds | TRunningEnvironment.CmdOut | TRunningEnvironment.CmdExit | TRunningEnvironment.RunningCmds | TRunningEnvironment.RunCode | TRunningEnvironment.TermData | TRunningEnvironment.TermStart | TRunningEnvironment.TermStartAck | TRunningEnvironment.TermResize;
payload: {

@@ -180,2 +180,35 @@ environmentID: string;

}
export interface RunningEnvironment_TermStart extends BaseRunningEnvironment {
type: TRunningEnvironment.TermStart;
payload: {
environmentID: string;
terminalID?: string;
messageID: string;
};
}
export interface RunningEnvironment_TermStartAck extends BaseRunningEnvironment {
type: TRunningEnvironment.TermStartAck;
payload: {
environmentID: string;
terminalID: string;
messageID: string;
};
}
export interface RunningEnvironment_TermData extends BaseRunningEnvironment {
type: TRunningEnvironment.TermData;
payload: {
environmentID: string;
terminalID: string;
data: string;
};
}
export interface RunningEnvironment_TermResize extends BaseRunningEnvironment {
type: TRunningEnvironment.TermResize;
payload: {
environmentID: string;
terminalID: string;
cols: number;
rows: number;
};
}
/**

@@ -182,0 +215,0 @@ * Received from remote Runner when an environments prints to stdout.

@@ -46,3 +46,19 @@ import { Filesystem } from './runningEnvironment/filesystem';

}
export interface TerminalSession {
sendData: (data: string) => void;
resize: ({ cols, rows }: {
cols: number;
rows: number;
}) => void;
destroy: () => void;
}
/**
* Methods for managing terminal sessions.
*
* This object is used internally by the `Terminal` component from Devbook UI package - https://github.com/devbookhq/ui#terminal.
*/
export interface Terminal {
createSession: (onData: (data: string) => void, activeTerminalID?: string) => Promise<TerminalSession>;
}
/**
* States of a {@link Devbook} connection to a VM.

@@ -75,5 +91,2 @@ */

private executionID;
private _sessionID?;
private get sessionID();
private set sessionID(value);
private _isDestroyed;

@@ -95,6 +108,7 @@ private get isDestroyed();

private get env();
readonly terminal: Terminal;
/**
* Use this for accessing and manipulating this `Devbook`'s VM's filesystem.
*/
get fs(): FS;
readonly fs: FS;
constructor(opts: {

@@ -122,8 +136,2 @@ /**

/**
* This function will be called when the URL for accessing this `Devbook`'s environment changes.
*
* You can assemble URL for any port by using the `getURL` function from the parameter.
*/
onURLChange?: (getURL: (port: number) => string | undefined) => void;
/**
* If this value is true then this `Devbook` will print detailed logs.

@@ -138,10 +146,2 @@ */

/**
* Compose the URL that can be used for connecting to a port on the environment defined in this `Devbook`'s constructor.
*
* @param port Number of the port that the URL should be connecting to.
* @returns URL address that allows you to connect to a specified port on this `Devbook`'s environment
* or `undefined` if this `Devbook` is not yet connected to a VM.
*/
getURL(port: number): string | undefined;
/**
* Run `command` in the VM.

@@ -153,3 +153,3 @@ *

*/
runCmd(command: string): void;
runCmd(command: string): Promise<void>;
/**

@@ -156,0 +156,0 @@ * Disconnect this `Devbook` from the VM.

@@ -14,3 +14,2 @@ import * as rws from '../common-ts/RunnerWebSocket';

status: SessionStatus;
sessionID?: string;
}) => void;

@@ -23,4 +22,7 @@ onEnvChange?: (env: RunningEnvironment) => void;

private get contextID();
private cmdExitSubscribers;
private fsWriteSubscribers;
private fileContentSubscribers;
private termDataSubscribers;
private termStartAckSubscribers;
readonly env: RunningEnvironment;

@@ -54,3 +56,25 @@ private readonly unsubscribeConnHandler;

command: string;
}): Promise<void>;
startTerminal({ terminalID }: {
terminalID?: string;
}): Promise<string>;
resizeTerminal({ terminalID, cols, rows }: {
terminalID: string;
cols: number;
rows: number;
}): void;
sendTerminalData({ terminalID, data }: {
terminalID: string;
data: string;
}): void;
onTerminalData({ terminalID, onData }: {
terminalID: string;
onData: (data: string) => void;
}): () => void;
private subscribeCmdExit;
private unsubscribeCmdExit;
private subscribeTermStartAck;
private unsubscribeTermStartAck;
private subscribeTermData;
private unsubscribeTermData;
private subscribeFileContent;

@@ -63,2 +87,4 @@ private unsubscribeFileContent;

private handleConnectionMessage;
private vmenv_handleTermStartAck;
private vmenv_handleTermData;
private vmenv_handleFSEventCreate;

@@ -65,0 +91,0 @@ private vmenv_handleFSEventRemove;

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

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

@@ -5,3 +5,5 @@ import EvaluationContext, { EvaluationContextOpts } from './evaluationContext';

private logger;
static config: Config;
static config: Config & {
logging?: boolean;
};
private static _obj;

@@ -8,0 +10,0 @@ static get obj(): Runner;

@@ -49,2 +49,18 @@ import { Env } from '../devbook';

}): void;
export { start, execCmd, writeFile, deleteFile, getFile, createDir, listDir, };
declare function termData(conn: WebSocketConnection, { environmentID, terminalID, data, }: {
environmentID: string;
terminalID: string;
data: string;
}): void;
declare function termResize(conn: WebSocketConnection, { environmentID, terminalID, cols, rows, }: {
environmentID: string;
terminalID: string;
cols: number;
rows: number;
}): void;
declare function termStart(conn: WebSocketConnection, { environmentID, terminalID, messageID, }: {
environmentID: string;
terminalID?: string;
messageID: string;
}): void;
export { start, execCmd, writeFile, deleteFile, getFile, createDir, listDir, termStart, termData, termResize, };
import * as rws from '../common-ts/RunnerWebSocket';
export interface Opts {
domain: string;
logging?: boolean;
}
interface Handler {
onMessage: (msg: rws.BaseMessage) => void;
onOpen: (sessionID: string) => void;
onOpen: () => void;
onClose: () => void;

@@ -21,3 +22,3 @@ }

get isConnecting(): boolean | undefined;
constructor({ domain }: Opts);
constructor({ domain, logging }: Opts);
subscribeHandler(handler: Handler): () => void;

@@ -24,0 +25,0 @@ connect(sessionID?: string): void;

export { useDevbook } from './react';
export type { Opts as UseDevbookOpts, } from './react';
export { Devbook, DevbookStatus, } from './core';
export type { Config, Env, } from './core';
export type { Config, Env, Terminal, TerminalSession, FS, } from './core';

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

import{useState as t,useCallback as e,useEffect as n}from"react";class i{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)}}
import{useState as t,useCallback as e,useEffect as n}from"react";
/*! *****************************************************************************

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

PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */function s(t,e,n,i){return new(n||(n=Promise))((function(s,o){function r(t){try{h(i.next(t))}catch(t){o(t)}}function a(t){try{h(i.throw(t))}catch(t){o(t)}}function h(t){var e;t.done?s(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(r,a)}h((i=i.apply(t,e||[])).next())}))}function o(t){return new Promise((e=>setTimeout(e,t)))}var r,a,h;!function(t){t.Error="Runner.Error"}(r||(r={})),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"}(a||(a={})),function(t){t.Error="CodeCell.Error"}(h||(h={}));const l={Runner:r,RunningEnvironment:a,CodeCell:h};class c{constructor({domain:t}){this.logger=new i("WebSocketConnection"),this.handlers=[],this.url=`wss://${t}`}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 s(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 2.5s"),yield o(2500),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(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((t=>t.onMessage(n)))):this.logger.error("Runner error",n):this.logger.error('Message "type" field has unexpected value',n)}}var d,u;!function(t){t.Ok="Ok",t.Terminated="Terminated"}(d||(d={}));class g{constructor({id:t,url:e}){this.logger=new i("RunnerSession"),this.lastPing=new Date,this.id=t,this.url=e}ping(){return s(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===d.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"}(u||(u={}));class m{constructor({conn:t,domain:e}){this.logger=new i("SessionManager"),this.userActivity=Promise.resolve(),this.isGettingSessionActive=!1,this.status=u.Disconnected,this.conn=t,this.url=`https://${e}`,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))}stop(){var t;null===(t=this.startActivity)||void 0===t||t.call(this),this.userActivity=new Promise((t=>{this.startActivity=t})),this.reset()}start(){var t;null===(t=this.startActivity)||void 0===t||t.call(this)}reset(){this.logger.log("Reset"),this.status=u.Disconnected,this.cachedSessionID=null,this.conn.close(),this.session=void 0}getSession(){var t;return s(this,void 0,void 0,(function*(){if(!this.isGettingSessionActive)for(this.isGettingSessionActive=!0;;){this.status=u.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 2.5s",n.headers,i),yield o(2500);continue}for(this.session=new g({id:i.sessionID,url:this.url}),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.userActivity,yield this.session.ping(),yield o(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=u.Disconnected,this.conn.close()}catch(t){this.logger.error("Failed to acquire Runner session. Will try again in 2.5s",t),yield o(2500)}}}))}}function p(t,e){for(var n=0,i=t.length-1;i>=0;i--){var s=t[i];"."===s?t.splice(i,1):".."===s?(t.splice(i,1),n++):n&&(t.splice(i,1),n--)}if(e)for(;n--;n)t.unshift("..");return t}var v=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/,f=function(t){return v.exec(t).slice(1)};function y(){for(var t="",e=!1,n=arguments.length-1;n>=-1&&!e;n--){var i=n>=0?arguments[n]:"/";if("string"!=typeof i)throw new TypeError("Arguments to path.resolve must be strings");i&&(t=i+"/"+t,e="/"===i.charAt(0))}return(e?"/":"")+(t=p(S(t.split("/"),(function(t){return!!t})),!e).join("/"))||"."}function D(t){var e=C(t),n="/"===b(t,-1);return(t=p(S(t.split("/"),(function(t){return!!t})),!e).join("/"))||e||(t="."),t&&n&&(t+="/"),(e?"/":"")+t}function C(t){return"/"===t.charAt(0)}var w={extname:function(t){return f(t)[3]},basename:function(t,e){var n=f(t)[2];return e&&n.substr(-1*e.length)===e&&(n=n.substr(0,n.length-e.length)),n},dirname:function(t){var e=f(t),n=e[0],i=e[1];return n||i?(i&&(i=i.substr(0,i.length-1)),n+i):"."},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=y(t).substr(1),e=y(e).substr(1);for(var i=n(t.split("/")),s=n(e.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 t=Array.prototype.slice.call(arguments,0);return D(S(t,(function(t,e){if("string"!=typeof t)throw new TypeError("Arguments to path.join must be strings");return t})).join("/"))},isAbsolute:C,normalize:D,resolve:y};function S(t,e){if(t.filter)return t.filter(e);for(var n=[],i=0;i<t.length;i++)e(t[i],i,t)&&n.push(t[i]);return n}var E,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 I{get level(){return w.normalize(this.path).split(w.sep).length-1}}function R(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 F extends I{constructor({name:t,parent:e,onAddItem:n}){super(),this.children=[],this.name=t,this.parent=e,this.addItemHandler=n,this.path=w.join(this.parent.path,this.name)}removeChildNode(t){this.children=this.children.filter((e=>e!==t))}serialize(t,e,n){const i=this.children.map((i=>i.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:R(i)}}}class _ extends I{constructor({name:t,parent:e}){super(),this.name=t,this.parent=e,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:t,forNode:e,onConfirm:n,onBlur:i}){super(),this.name="name-prompt",this.parent=t,this.forNode=e,this.path=w.join(t.path,this.name),this.onConfirm=n,this.onBlur=i}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 k extends I{constructor({onAddItem:t}){super(),this.name="/",this.path="/",this.parent=void 0,this.children=[],this.addItemHandler=t}serialize(t,e,n){const i=this.children.map((i=>i.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:R(i)}}}class x extends I{constructor({parent:t}){super(),this.name="empty-node",this.parent=t,this.path=w.join(this.parent.path,this.name)}serialize(){return{type:"Empty",key:this.path,title:"Empty Directory",isLeaf:!0,disabled:!0}}}class L{constructor(){this.logger=new i("Filesystem"),this.root=new k({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 k||n instanceof F))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 i;i="Dir"===e.type?new F({name:e.name,parent:n,onAddItem:({event:t,dir:e,type:n})=>this.showPrompt({event:t,parent:e,type:n})}):new _({name:e.name,parent:n}),1===n.children.length&&n.children[0]instanceof x?n.children=[i]:n.children.push(i),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 k||n instanceof F))throw new Error(`Node at '${t}' is not a directory or root node`);const i=n.children.length;n.children=n.children.filter((t=>t.name!==e.name));i!==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 k||t instanceof F))throw new Error(`Node at '${e.dirPath}' is not a directory or a root node`);const n=t.children.find((t=>t instanceof P));if(e.content.length){const n=[];for(const i of e.content){let e;e="Dir"===i.type?new F({name:i.name,parent:t,onAddItem:({event:t,dir:e,type:n})=>this.showPrompt({event:t,parent:e,type:n})}):new _({name:i.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:i}=t;if(this.logger.log("Show prompt",{parent:n,type:i}),n.children.some((t=>t instanceof P)))return;e.preventDefault();const s=new P({parent:n,forNode:i,onConfirm:((t,e)=>{if(this.logger.log("Prompt confirm",{prompt:t,name:e}),!e)return;const n=t.parent.path,s=w.join(t.parent.path,e);this.removeFromParent(t),this.notifyOnDirsChangeLs({dirPaths:[n]}),this.notifyOnNewItemConfirmLs({fullPath:s,name:e,type:i})}).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(s),this.notifyOnDirsChangeLs({dirPaths:[s.parent.path]}),this.notifyOnShowPromptLs({dirPath:s.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 i of t.children)i instanceof F?this.print(i,e+1):console.log(n+" "+i.path,`(${i.name})`)}find(t,e=this.root){if(this.logger.log("Find (recursion)",{currentPath:e.path,targetPath:t}),t=w.normalize(t),e.path===t)return e;const n=t.split(w.sep).length-1;if(!(e.level>n)&&(e instanceof k||e instanceof F))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 k||e instanceof F))throw new Error("Parent is not a dir or root");const n=new F({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(w.sep);let n,i="/";for(const t of e)if(i=w.join(i,t),!this.find(i)){const e=w.dirname(i);n=this.mkDir({parentPath:e,name:t})}return n}removeFromParent(t){const{parent:e}=t;(e instanceof k||e instanceof F)&&(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 O(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"}(E||(E={}));class N{constructor(t,e){this.contextID=t,this.templateID=e,this.output=[],this.filesystem=new L,this.isReady=!1,this.id=`${t}_${O(e)}`}restart(){this.output=[],this.isReady=!1,this.filesystem.setDirsContent([{dirPath:"/",content:[]}])}logOutput(t,e){this.output=[...this.output,{message:t,source:e}]}}function A(t,{environmentID:e,templateID:n}){const i={type:l.RunningEnvironment.Start,payload:{environmentID:e,templateID:n}};t.send(i)}class ${constructor(t){var e,n;this.opts=t,this.fsWriteSubscribers=[],this.fileContentSubscribers=[],this.logger=new i(`EvaluationContext [${t.templateID}]`,t.debug),this.env=new N(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(),A(this.opts.conn,{environmentID:this.env.id,templateID:this.env.templateID}),null===(n=(e=this.opts).onEnvChange)||void 0===n||n.call(e,this.env)}get contextID(){return this.opts.contextID}restart(){this.logger.log("Restart",this.opts.conn.sessionID),this.env.restart(),A(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 s(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)})),i=n=>{n.path.endsWith(t)&&e(n.content)};this.subscribeFileContent(i),function(t,{environmentID:e,path:n}){const i={type:l.RunningEnvironment.GetFile,payload:{environmentID:e,path:n}};t.send(i)}(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(i)}}))}deleteFile({path:t}){this.logger.log("Delete file",{filepath:t}),function(t,{environmentID:e,path:n}){const i={type:l.RunningEnvironment.RemoveFile,payload:{environmentID:e,path:n}};t.send(i)}(this.opts.conn,{environmentID:this.env.id,path:t})}updateFile({path:t,content:e}){return s(this,void 0,void 0,(function*(){let n;this.logger.log("Update file",{filepath:t});const i=new Promise(((t,e)=>{n=t,setTimeout((()=>{e("Timeout")}),1e4)})),s=e=>{e.path.endsWith(t)&&n()};this.subscribeFSWrite(s),function(t,{environmentID:e,path:n,content:i}){const s={type:l.RunningEnvironment.WriteFile,payload:{environmentID:e,path:n,content:i}};t.send(s)}(this.opts.conn,{environmentID:this.env.id,path:t,content:e});try{yield i}catch(e){throw new Error(`File ${t} not written to VM: ${e}`)}finally{this.unsubscribeFSWrite(s)}}))}createDir({path:t}){this.logger.log("Create dir",{filepath:t}),function(t,{environmentID:e,path:n}){const i={type:l.RunningEnvironment.CreateDir,payload:{environmentID:e,path:n}};t.send(i)}(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 i={type:l.RunningEnvironment.ListDir,payload:{environmentID:e,path:n}};t.send(i)}(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:i}){const s={type:l.RunningEnvironment.ExecCmd,payload:{environmentID:e,executionID:n,command:i}};t.send(s)}(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:u.Connecting})}handleConnectionClose(){var t,e;null===(e=(t=this.opts).onSessionChange)||void 0===e||e.call(t,{status:u.Connecting})}handleConnectionMessage(t){switch(this.logger.log("Handling message from remote Runner",{message:t}),t.type){case l.RunningEnvironment.StartAck:{const e=t;this.vmenv_handleStartAck(e.payload);break}case l.RunningEnvironment.CmdOut:{const e=t;this.vmenv_handleCmdOut(e.payload);break}case l.RunningEnvironment.CmdExit:{const e=t;this.vmenv_handleCmdExit(e.payload);break}case l.RunningEnvironment.FSEventWrite:{const e=t;this.vmenv_handleFSEventWrite(e.payload);break}case l.RunningEnvironment.FileContent:{const e=t;this.vmenv_handleFileContent(e.payload);break}case l.RunningEnvironment.FSEventCreate:{const e=t;this.vmenv_handleFSEventCreate(e.payload);break}case l.RunningEnvironment.FSEventRemove:{const e=t;this.vmenv_handleFSEventRemove(e.payload);break}case l.RunningEnvironment.DirContent:{const e=t;this.vmenv_handleDirContent(e.payload);break}case l.RunningEnvironment.Stderr:{const e=t;this.vmenv_handleStderr(e.payload);break}case l.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=w.basename(t.path),n=w.dirname(t.path),i="Directory"===t.type?"Dir":"File";this.env.filesystem.addNodeToDir(n,{name:e,type:i})}vmenv_handleFSEventRemove(t){this.logger.log('[vmenv] Handling "FSEventRemove"',{payload:t});const e=w.basename(t.path),n=w.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=w.basename(n.path),i="Directory"===n.type?"Dir":"File";e.push({name:t,type:i})}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,i,s;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),null===(s=(i=this.opts).onSessionChange)||void 0===s||s.call(i,{status:u.Connected,sessionID:this.opts.conn.sessionID})}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,E.Stderr)}vmenv_handleStdout(t){this.logger.log('[vmenv] Handling "Stdout"',t),this.env.logOutput(t.message,E.Stdout)}}class M{constructor(){this.logger=new i("Runner"),this.conn=new c({domain:M.config.domain}),this.sessManager=new m({conn:this.conn,domain:M.config.domain})}static get obj(){if(!M.config)throw new Error("Config not set");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(t){return new $(Object.assign(Object.assign({},t),{conn:this.conn}))}__internal__start(){this.sessManager.start()}__internal__stop(){this.sessManager.stop()}__debug__loadNewSession(){this.logger.log("__debug__loadNewSession"),this.sessManager.reset()}}const W=(j="1234567890abcdefghijklmnopqrstuvwxyz",H=6,()=>{let t="",e=H;for(;e--;)t+=j[Math.random()*j.length|0];return t});var j,H,z;!function(t){t.Disconnected="Disconnected",t.Connecting="Connecting",t.Connected="Connected"}(z||(z={}));class T{constructor(t){if(this.opts=t,this.contextID="default",this.executionID=W(),this._isDestroyed=!1,this._isEnvReady=!1,this._sessionStatus=u.Disconnected,this._status=z.Disconnected,!t.config)throw new Error("Missing Devbook config");const e=this.getURL.bind(this),n=()=>this.opts.env,i=()=>this.executionID,s=t=>this.isEnvReady=t,o=t=>this.sessionStatus=t,r=t=>this.sessionID=t;M.config=this.opts.config,this.context=M.obj.createContext({debug:t.debug,templateID:t.env,contextID:this.contextID,onEnvChange(i){var o;i.templateID===n()&&(s(i.isReady),null===(o=t.onURLChange)||void 0===o||o.call(t,e))},onSessionChange({status:n,sessionID:i}){var s;r(i),o(n),null===(s=t.onURLChange)||void 0===s||s.call(t,e)},onCmdOut(e){var n,s;e.executionID===i()&&(void 0!==e.stdout&&(null===(n=t.onStdout)||void 0===n||n.call(t,e.stdout)),void 0!==e.stderr&&(null===(s=t.onStderr)||void 0===s||s.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===z.Connected&&this.sessionID&&this.env.isReady)return`https://${t}-${this.env.id}-${this.sessionID}.o.usedevbook.com`}runCmd(t){if(this.status!==z.Connected)throw new Error("Not connected to the VM yet.");this.executionID=W(),this.context.executeCommand({executionID:this.executionID,command:t})}destroy(){this.context.destroy(),this.isDestroyed=!0}__internal__start(){M.obj.__internal__start()}__internal__stop(){M.obj.__internal__stop()}listDir(t){if(this.status!==z.Connected)throw new Error("Not connected to the VM yet.");return this.context.listDir({path:t})}createDir(t){if(this.status!==z.Connected)throw new Error("Not connected to the VM yet.");return this.context.createDir({path:t})}deleteFile(t){if(this.status!==z.Connected)throw new Error("Not connected to the VM yet.");return this.context.deleteFile({path:t})}getFile(t){if(this.status!==z.Connected)throw new Error("Not connected to the VM yet.");return this.context.getFile({path:t})}writeFile(t,e){if(this.status!==z.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!==z.Disconnected&&(this.status=z.Disconnected));let t;switch(this.sessionStatus){case u.Disconnected:t=z.Disconnected;break;case u.Connecting:t=z.Connecting;break;case u.Connected:if(!this.isEnvReady){t=z.Connecting;break}t=z.Connected}this.status=t}}function G({env:i,debug:s,config:o}){const[r,a]=t(),[h,l]=t(z.Disconnected),[c,d]=t([]),[u,g]=t([]),m=e((t=>{r&&(g([]),d([]),r.runCmd(t))}),[r]);return n((function(){const t=new T({debug:s,env:i,onStatusChange(t){l(t)},onStderr(t){d((e=>[...e,t]))},onStdout(t){g((e=>[...e,t]))},config:o});return g([]),d([]),a(t),()=>{t.destroy()}}),[i,s,o]),{stderr:c,stdout:u,runCmd:m,status:h,fs:null==r?void 0:r.fs}}export{T as Devbook,z as DevbookStatus,G as useDevbook};
***************************************************************************** */function i(t,e,n,i){return new(n||(n=Promise))((function(s,o){function r(t){try{h(i.next(t))}catch(t){o(t)}}function a(t){try{h(i.throw(t))}catch(t){o(t)}}function h(t){var e;t.done?s(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(r,a)}h((i=i.apply(t,e||[])).next())}))}function s(t){return e="1234567890abcdefghijklmnopqrstuvwxyz",n=t,()=>{let t="",i=n;for(;i--;)t+=e[Math.random()*e.length|0];return t};var e,n}class o{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)}}function r(t){return new Promise((e=>setTimeout(e,t)))}var a,h,l;!function(t){t.Error="Runner.Error"}(a||(a={})),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.TermData="RunningEnvironment.TermData",t.TermResize="RunningEnvironment.TermResize",t.TermStart="RunningEnvironment.TermStart",t.TermStartAck="RunningEnvironment.TermStartAck",t.RunCode="RunningEnvironment.Run"}(h||(h={})),function(t){t.Error="CodeCell.Error"}(l||(l={}));const c={Runner:a,RunningEnvironment:h,CodeCell:l};class d{constructor({domain:t,logging:e}){this.handlers=[],this.url=`wss://${t}`,this.logger=new o("WebSocketConnection",e)}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.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(){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()))}_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 i(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 2.5s"),yield r(2500),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(c.RunningEnvironment).includes(n.type)||Object.values(c.Runner).includes(n.type)||Object.values(c.CodeCell).includes(n.type)?n.type!==c.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 u,m;!function(t){t.Ok="Ok",t.Terminated="Terminated"}(u||(u={}));class g{constructor({id:t,url:e}){this.logger=new o("RunnerSession"),this.lastPing=new Date,this.id=t,this.url=e}ping(){return i(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===u.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"}(m||(m={}));class v{constructor({conn:t,domain:e}){this.logger=new o("SessionManager"),this.userActivity=Promise.resolve(),this.isGettingSessionActive=!1,this.status=m.Disconnected,this.conn=t,this.url=`https://${e}`,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))}stop(){var t;null===(t=this.startActivity)||void 0===t||t.call(this),this.userActivity=new Promise((t=>{this.startActivity=t})),this.reset()}start(){var t;null===(t=this.startActivity)||void 0===t||t.call(this)}reset(){this.logger.log("Reset"),this.status=m.Disconnected,this.cachedSessionID=null,this.conn.close(),this.session=void 0}getSession(){var t;return i(this,void 0,void 0,(function*(){if(!this.isGettingSessionActive)for(this.isGettingSessionActive=!0;;){this.status=m.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 2.5s",n.headers,i),yield r(2500);continue}for(this.session=new g({id:i.sessionID,url:this.url}),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.userActivity,yield this.session.ping(),yield r(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=m.Disconnected,this.conn.close()}catch(t){this.logger.error("Failed to acquire Runner session. Will try again in 2.5s",t),yield r(2500)}}}))}}function p(t,e){for(var n=0,i=t.length-1;i>=0;i--){var s=t[i];"."===s?t.splice(i,1):".."===s?(t.splice(i,1),n++):n&&(t.splice(i,1),n--)}if(e)for(;n--;n)t.unshift("..");return t}var f=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/,D=function(t){return f.exec(t).slice(1)};function y(){for(var t="",e=!1,n=arguments.length-1;n>=-1&&!e;n--){var i=n>=0?arguments[n]:"/";if("string"!=typeof i)throw new TypeError("Arguments to path.resolve must be strings");i&&(t=i+"/"+t,e="/"===i.charAt(0))}return(e?"/":"")+(t=p(w(t.split("/"),(function(t){return!!t})),!e).join("/"))||"."}function b(t){var e=C(t),n="/"===I(t,-1);return(t=p(w(t.split("/"),(function(t){return!!t})),!e).join("/"))||e||(t="."),t&&n&&(t+="/"),(e?"/":"")+t}function C(t){return"/"===t.charAt(0)}var S={extname:function(t){return D(t)[3]},basename:function(t,e){var n=D(t)[2];return e&&n.substr(-1*e.length)===e&&(n=n.substr(0,n.length-e.length)),n},dirname:function(t){var e=D(t),n=e[0],i=e[1];return n||i?(i&&(i=i.substr(0,i.length-1)),n+i):"."},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=y(t).substr(1),e=y(e).substr(1);for(var i=n(t.split("/")),s=n(e.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 t=Array.prototype.slice.call(arguments,0);return b(w(t,(function(t,e){if("string"!=typeof t)throw new TypeError("Arguments to path.join must be strings");return t})).join("/"))},isAbsolute:C,normalize:b,resolve:y};function w(t,e){if(t.filter)return t.filter(e);for(var n=[],i=0;i<t.length;i++)e(t[i],i,t)&&n.push(t[i]);return n}var E,I="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 R{get level(){return S.normalize(this.path).split(S.sep).length-1}}function _(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 k extends R{constructor({name:t,parent:e,onAddItem:n}){super(),this.children=[],this.name=t,this.parent=e,this.addItemHandler=n,this.path=S.join(this.parent.path,this.name)}removeChildNode(t){this.children=this.children.filter((e=>e!==t))}serialize(t,e,n){const i=this.children.map((i=>i.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:_(i)}}}class F extends R{constructor({name:t,parent:e}){super(),this.name=t,this.parent=e,this.path=S.join(this.parent.path,this.name)}serialize(){return{type:"File",key:this.path,title:this.name,isLeaf:!0}}}class x extends R{constructor({parent:t,forNode:e,onConfirm:n,onBlur:i}){super(),this.name="name-prompt",this.parent=t,this.forNode=e,this.path=S.join(t.path,this.name),this.onConfirm=n,this.onBlur=i}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 P extends R{constructor({onAddItem:t}){super(),this.name="/",this.path="/",this.parent=void 0,this.children=[],this.addItemHandler=t}serialize(t,e,n){const i=this.children.map((i=>i.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:_(i)}}}class O extends R{constructor({parent:t}){super(),this.name="empty-node",this.parent=t,this.path=S.join(this.parent.path,this.name)}serialize(){return{type:"Empty",key:this.path,title:"Empty Directory",isLeaf:!0,disabled:!0}}}class A{constructor(){this.logger=new o("Filesystem"),this.root=new P({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 P||n instanceof k))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 i;i="Dir"===e.type?new k({name:e.name,parent:n,onAddItem:({event:t,dir:e,type:n})=>this.showPrompt({event:t,parent:e,type:n})}):new F({name:e.name,parent:n}),1===n.children.length&&n.children[0]instanceof O?n.children=[i]:n.children.push(i),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 P||n instanceof k))throw new Error(`Node at '${t}' is not a directory or root node`);const i=n.children.length;n.children=n.children.filter((t=>t.name!==e.name));i!==n.children.length?(0===n.children.length&&(n.children=[new O({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 P||t instanceof k))throw new Error(`Node at '${e.dirPath}' is not a directory or a root node`);const n=t.children.find((t=>t instanceof x));if(e.content.length){const n=[];for(const i of e.content){let e;e="Dir"===i.type?new k({name:i.name,parent:t,onAddItem:({event:t,dir:e,type:n})=>this.showPrompt({event:t,parent:e,type:n})}):new F({name:i.name,parent:t}),n.push(e)}t.children=n}else t.children=[new O({parent:t})];n&&t.children.push(n)}this.notifyOnDirsChangeLs({dirPaths:t.map((t=>t.dirPath))})}showPrompt(t){const{event:e,parent:n,type:i}=t;if(this.logger.log("Show prompt",{parent:n,type:i}),n.children.some((t=>t instanceof x)))return;e.preventDefault();const s=new x({parent:n,forNode:i,onConfirm:((t,e)=>{if(this.logger.log("Prompt confirm",{prompt:t,name:e}),!e)return;const n=t.parent.path,s=S.join(t.parent.path,e);this.removeFromParent(t),this.notifyOnDirsChangeLs({dirPaths:[n]}),this.notifyOnNewItemConfirmLs({fullPath:s,name:e,type:i})}).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(s),this.notifyOnDirsChangeLs({dirPaths:[s.parent.path]}),this.notifyOnShowPromptLs({dirPath:s.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 i of t.children)i instanceof k?this.print(i,e+1):console.log(n+" "+i.path,`(${i.name})`)}find(t,e=this.root){if(this.logger.log("Find (recursion)",{currentPath:e.path,targetPath:t}),t=S.normalize(t),e.path===t)return e;const n=t.split(S.sep).length-1;if(!(e.level>n)&&(e instanceof P||e instanceof k))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 P||e instanceof k))throw new Error("Parent is not a dir or root");const n=new k({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(S.sep);let n,i="/";for(const t of e)if(i=S.join(i,t),!this.find(i)){const e=S.dirname(i);n=this.mkDir({parentPath:e,name:t})}return n}removeFromParent(t){const{parent:e}=t;(e instanceof P||e instanceof k)&&(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 T(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"}(E||(E={}));class N{constructor(t,e){this.contextID=t,this.templateID=e,this.output=[],this.filesystem=new A,this.isReady=!1,this.id=`${t}_${T(e)}`}restart(){this.output=[],this.isReady=!1,this.filesystem.setDirsContent([{dirPath:"/",content:[]}])}logOutput(t,e){this.output=[...this.output,{message:t,source:e}]}}function L(t,{environmentID:e,templateID:n}){const i={type:c.RunningEnvironment.Start,payload:{environmentID:e,templateID:n}};t.send(i)}const $=s(6);class M{constructor(t){var e,n;this.opts=t,this.cmdExitSubscribers=[],this.fsWriteSubscribers=[],this.fileContentSubscribers=[],this.termDataSubscribers=[],this.termStartAckSubscribers=[],this.logger=new o(`EvaluationContext [${t.templateID}]`,t.debug),this.env=new N(this.contextID,t.templateID);this.unsubscribeConnHandler=this.opts.conn.subscribeHandler({onOpen:()=>this.handleConnectionOpen(),onMessage:t=>this.handleConnectionMessage(t),onClose:()=>this.handleConnectionClose()}),this.opts.conn.isOpen&&this.handleConnectionOpen(),this.opts.conn.isClosed&&this.handleConnectionClose(),L(this.opts.conn,{environmentID:this.env.id,templateID:this.env.templateID}),null===(n=(e=this.opts).onEnvChange)||void 0===n||n.call(e,this.env)}get contextID(){return this.opts.contextID}restart(){this.logger.log("Restart",this.opts.conn.sessionID),this.env.restart(),L(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 i(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)})),i=n=>{n.path.endsWith(t)&&e(n.content)};this.subscribeFileContent(i),function(t,{environmentID:e,path:n}){const i={type:c.RunningEnvironment.GetFile,payload:{environmentID:e,path:n}};t.send(i)}(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(i)}}))}deleteFile({path:t}){this.logger.log("Delete file",{filepath:t}),function(t,{environmentID:e,path:n}){const i={type:c.RunningEnvironment.RemoveFile,payload:{environmentID:e,path:n}};t.send(i)}(this.opts.conn,{environmentID:this.env.id,path:t})}updateFile({path:t,content:e}){return i(this,void 0,void 0,(function*(){let n;this.logger.log("Update file",{filepath:t});const i=new Promise(((t,e)=>{n=t,setTimeout((()=>{e("Timeout")}),1e4)})),s=e=>{e.path.endsWith(t)&&n()};this.subscribeFSWrite(s),function(t,{environmentID:e,path:n,content:i}){const s={type:c.RunningEnvironment.WriteFile,payload:{environmentID:e,path:n,content:i}};t.send(s)}(this.opts.conn,{environmentID:this.env.id,path:t,content:e});try{yield i}catch(e){throw new Error(`File ${t} not written to VM: ${e}`)}finally{this.unsubscribeFSWrite(s)}}))}createDir({path:t}){this.logger.log("Create dir",{filepath:t}),function(t,{environmentID:e,path:n}){const i={type:c.RunningEnvironment.CreateDir,payload:{environmentID:e,path:n}};t.send(i)}(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 i={type:c.RunningEnvironment.ListDir,payload:{environmentID:e,path:n}};t.send(i)}(this.opts.conn,{environmentID:this.env.id,path:t})}executeCommand({executionID:t,command:e}){return i(this,void 0,void 0,(function*(){let n;this.logger.log("Execute shell command",{executionID:t,command:e});let i=!1;const s=new Promise(((t,e)=>{n=t,setTimeout((()=>{i||e("Timeout")}),1e4)})),o=e=>{e.executionID===t&&(n(t),i=!0)};this.subscribeCmdExit(o),function(t,{environmentID:e,executionID:n,command:i}){const s={type:c.RunningEnvironment.ExecCmd,payload:{environmentID:e,executionID:n,command:i}};t.send(s)}(this.opts.conn,{environmentID:this.env.id,executionID:t,command:e});try{yield s}catch(t){throw new Error(`Can't exit cmd: ${t}`)}finally{this.unsubscribeCmdExit(o)}}))}startTerminal({terminalID:t}){return i(this,void 0,void 0,(function*(){this.logger.log("Start terminal",{terminalID:t});const e=$();let n,i=!1;const s=new Promise(((t,e)=>{n=t,setTimeout((()=>{i||e("Timeout")}),1e4)})),o=t=>{t.messageID===e&&(n(t.terminalID),i=!0)};this.subscribeTermStartAck(o),function(t,{environmentID:e,terminalID:n,messageID:i}){const s={type:c.RunningEnvironment.TermStart,payload:{environmentID:e,terminalID:n,messageID:i}};t.send(s)}(this.opts.conn,{environmentID:this.env.id,terminalID:t,messageID:e});try{return yield s}catch(t){throw new Error(`Can't start terminal session: ${t}`)}finally{this.unsubscribeTermStartAck(o)}}))}resizeTerminal({terminalID:t,cols:e,rows:n}){this.logger.log("Resize terminal",{terminalID:t,cols:e,rows:n}),function(t,{environmentID:e,terminalID:n,cols:i,rows:s}){const o={type:c.RunningEnvironment.TermResize,payload:{environmentID:e,terminalID:n,cols:i,rows:s}};t.send(o)}(this.opts.conn,{environmentID:this.env.id,terminalID:t,cols:e,rows:n})}sendTerminalData({terminalID:t,data:e}){this.logger.log("Send terminal data",{terminalID:t}),function(t,{environmentID:e,terminalID:n,data:i}){const s={type:c.RunningEnvironment.TermData,payload:{environmentID:e,terminalID:n,data:i}};t.send(s)}(this.opts.conn,{environmentID:this.env.id,terminalID:t,data:e})}onTerminalData({terminalID:t,onData:e}){const n=n=>{n.terminalID===t&&e(n.data)};return this.subscribeTermData(n),()=>this.unsubscribeTermData(n)}subscribeCmdExit(t){this.cmdExitSubscribers.push(t)}unsubscribeCmdExit(t){const e=this.cmdExitSubscribers.indexOf(t);e>-1&&this.cmdExitSubscribers.splice(e,1)}subscribeTermStartAck(t){this.termStartAckSubscribers.push(t)}unsubscribeTermStartAck(t){const e=this.termStartAckSubscribers.indexOf(t);e>-1&&this.termStartAckSubscribers.splice(e,1)}subscribeTermData(t){this.termDataSubscribers.push(t)}unsubscribeTermData(t){const e=this.termDataSubscribers.indexOf(t);e>-1&&this.termDataSubscribers.splice(e,1)}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(){var t,e;this.restart(),null===(e=(t=this.opts).onSessionChange)||void 0===e||e.call(t,{status:m.Connecting})}handleConnectionClose(){var t,e;null===(e=(t=this.opts).onSessionChange)||void 0===e||e.call(t,{status:m.Connecting})}handleConnectionMessage(t){switch(this.logger.log("Handling message from remote Runner",{message:t}),t.type){case c.RunningEnvironment.StartAck:{const e=t;this.vmenv_handleStartAck(e.payload);break}case c.RunningEnvironment.CmdOut:{const e=t;this.vmenv_handleCmdOut(e.payload);break}case c.RunningEnvironment.CmdExit:{const e=t;this.vmenv_handleCmdExit(e.payload);break}case c.RunningEnvironment.FSEventWrite:{const e=t;this.vmenv_handleFSEventWrite(e.payload);break}case c.RunningEnvironment.FileContent:{const e=t;this.vmenv_handleFileContent(e.payload);break}case c.RunningEnvironment.FSEventCreate:{const e=t;this.vmenv_handleFSEventCreate(e.payload);break}case c.RunningEnvironment.FSEventRemove:{const e=t;this.vmenv_handleFSEventRemove(e.payload);break}case c.RunningEnvironment.DirContent:{const e=t;this.vmenv_handleDirContent(e.payload);break}case c.RunningEnvironment.Stderr:{const e=t;this.vmenv_handleStderr(e.payload);break}case c.RunningEnvironment.Stdout:{const e=t;this.vmenv_handleStdout(e.payload);break}case c.RunningEnvironment.TermData:{const e=t;this.vmenv_handleTermData(e.payload);break}case c.RunningEnvironment.TermStartAck:{const e=t;this.vmenv_handleTermStartAck(e.payload);break}default:this.logger.warn("Unknown message type",{message:t})}}vmenv_handleTermStartAck(t){this.logger.log('[vmenv] Handling "TermStartAck"',t),this.termStartAckSubscribers.forEach((e=>e(t)))}vmenv_handleTermData(t){this.logger.log('[vmenv] Handling "TermData"',t),this.termDataSubscribers.forEach((e=>e(t)))}vmenv_handleFSEventCreate(t){this.logger.log('[vmenv] Handling "FSEventCreate"',t);const e=S.basename(t.path),n=S.dirname(t.path),i="Directory"===t.type?"Dir":"File";this.env.filesystem.addNodeToDir(n,{name:e,type:i})}vmenv_handleFSEventRemove(t){this.logger.log('[vmenv] Handling "FSEventRemove"',{payload:t});const e=S.basename(t.path),n=S.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=S.basename(n.path),i="Directory"===n.type?"Dir":"File";e.push({name:t,type:i})}this.env.filesystem.setDirsContent([{dirPath:t.dirPath,content:e}])}vmenv_handleCmdExit(t){var e,n;this.logger.log('[vmenv] Handling "CmdExit"',t),this.cmdExitSubscribers.forEach((e=>e(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,i,s;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),null===(s=(i=this.opts).onSessionChange)||void 0===s||s.call(i,{status:m.Connected})}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,E.Stderr)}vmenv_handleStdout(t){this.logger.log('[vmenv] Handling "Stdout"',t),this.env.logOutput(t.message,E.Stdout)}}class j{constructor(){this.logger=new o("Runner"),this.conn=new d({domain:j.config.domain,logging:j.config.logging}),this.sessManager=new v({conn:this.conn,domain:j.config.domain})}static get obj(){if(!j.config)throw new Error("Config not set");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(t){return new M(Object.assign(Object.assign({},t),{conn:this.conn}))}__internal__start(){this.sessManager.start()}__internal__stop(){this.sessManager.stop()}__debug__loadNewSession(){this.logger.log("__debug__loadNewSession"),this.sessManager.reset()}}const W=s(6);var z;!function(t){t.Disconnected="Disconnected",t.Connecting="Connecting",t.Connected="Connected"}(z||(z={}));class H{constructor(t){if(this.opts=t,this.contextID="default",this.executionID=W(),this._isDestroyed=!1,this._isEnvReady=!1,this._sessionStatus=m.Disconnected,this._status=z.Disconnected,!t.config)throw new Error("Missing Devbook config");const e=()=>this.opts.env,n=()=>this.executionID,s=t=>this.isEnvReady=t,o=t=>this.sessionStatus=t;j.config=Object.assign(Object.assign({},this.opts.config),{logging:t.debug}),this.context=j.obj.createContext({debug:t.debug,templateID:t.env,contextID:this.contextID,onEnvChange(t){t.templateID===e()&&s(t.isReady)},onSessionChange({status:t}){o(t)},onCmdOut(e){var i,s;e.executionID===n()&&(void 0!==e.stdout&&(null===(i=t.onStdout)||void 0===i||i.call(t,e.stdout)),void 0!==e.stderr&&(null===(s=t.onStderr)||void 0===s||s.call(t,e.stderr)))}}),this.fs={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:this.env.filesystem.addListener.bind(this.env.filesystem),removeListener:this.env.filesystem.removeListener.bind(this.env.filesystem),serialize:this.env.filesystem.serialize.bind(this.env.filesystem)},this.terminal={createSession:(t,e)=>i(this,void 0,void 0,(function*(){const n=yield this.context.startTerminal({terminalID:e}),i=this.context.onTerminalData({onData:t,terminalID:n});return{destroy:()=>{i()},sendData:t=>{this.context.sendTerminalData({terminalID:n,data:t})},resize:({cols:t,rows:e})=>{this.context.resizeTerminal({terminalID:n,cols:t,rows:e})}}}))}}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}runCmd(t){if(this.status!==z.Connected)throw new Error("Not connected to the VM yet.");return this.executionID=W(),this.context.executeCommand({executionID:this.executionID,command:t})}destroy(){this.context.destroy(),this.isDestroyed=!0}__internal__start(){j.obj.__internal__start()}__internal__stop(){j.obj.__internal__stop()}listDir(t){if(this.status!==z.Connected)throw new Error("Not connected to the VM yet.");return this.context.listDir({path:t})}createDir(t){if(this.status!==z.Connected)throw new Error("Not connected to the VM yet.");return this.context.createDir({path:t})}deleteFile(t){if(this.status!==z.Connected)throw new Error("Not connected to the VM yet.");return this.context.deleteFile({path:t})}getFile(t){if(this.status!==z.Connected)throw new Error("Not connected to the VM yet.");return this.context.getFile({path:t})}writeFile(t,e){if(this.status!==z.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!==z.Disconnected&&(this.status=z.Disconnected));let t;switch(this.sessionStatus){case m.Disconnected:t=z.Disconnected;break;case m.Connecting:t=z.Connecting;break;case m.Connected:if(!this.isEnvReady){t=z.Connecting;break}t=z.Connected}this.status=t}}function G({env:s,debug:o,config:r}){const[a,h]=t(),[l,c]=t(z.Disconnected),[d,u]=t([]),[m,g]=t([]),v=e((t=>i(this,void 0,void 0,(function*(){a&&(g([]),u([]),a.runCmd(t))}))),[a]);return n((function(){const t=new H({debug:o,env:s,config:{domain:r.domain},onStatusChange(t){c(t)},onStderr(t){u((e=>[...e,t]))},onStdout(t){g((e=>[...e,t]))}});return g([]),u([]),h(t),()=>{t.destroy()}}),[s,o,r.domain]),{stderr:d,stdout:m,runCmd:v,status:l,fs:null==a?void 0:a.fs,terminal:null==a?void 0:a.terminal}}export{H as Devbook,z as DevbookStatus,G as useDevbook};
//# sourceMappingURL=index.js.map

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

import { DevbookStatus, Env, FS, Config } from '../core';
import { DevbookStatus, Env, FS, Terminal, Config } from '../core';
/**

@@ -50,3 +50,3 @@ * Options passed to the {@link useDevbook} hook.

*/
runCmd: (command: string) => void;
runCmd: (command: string) => Promise<void>;
/**

@@ -56,2 +56,8 @@ * Use this for accessing and manipulating this Devbook's VM's filesystem.

fs?: FS;
/**
* Use this for managing terminal sessions.
*
* This object is used internally by the `Terminal` component from Devbook UI package - https://github.com/devbookhq/ui#terminal.
*/
terminal?: Terminal;
}

@@ -58,0 +64,0 @@ /**

@@ -26,2 +26,6 @@ export declare enum TRunner {

RunningCmds = "RunningEnvironment.RunningCmds",
TermData = "RunningEnvironment.TermData",
TermResize = "RunningEnvironment.TermResize",
TermStart = "RunningEnvironment.TermStart",
TermStartAck = "RunningEnvironment.TermStartAck",
RunCode = "RunningEnvironment.Run"

@@ -28,0 +32,0 @@ }

export { TRunner, TRunningEnvironment, TCodeCell, MessageType, } from './BaseMessage';
export type { BaseMessage, } from './BaseMessage';
export type { BaseRunningEnvironment, RunningEnvironment_Start, RunningEnvironment_StartAck, RunningEnvironment_Eval, RunningEnvironment_FSEventCreate, RunningEnvironment_FSEventRemove, RunningEnvironment_FSEventWrite, RunningEnvironment_CreateDir, RunningEnvironment_RemoveFile, RunningEnvironment_ListDir, RunningEnvironment_FileContent, RunningEnvironment_WriteFile, RunningEnvironment_DirContent, RunningEnvironment_GetFile, RunningEnvironment_Stdout, RunningEnvironment_Stderr, RunningEnvironment_ExecCmd, RunningEnvironment_KillCmd, RunningEnvironment_ListRunningCmds, RunningEnvironment_CmdOut, RunningEnvironment_CmdExit, RunningEnvironment_RunningCmds, RunningEnvironment_RunCode, } from './RunningEnvironmentMessage';
export type { BaseRunningEnvironment, RunningEnvironment_Start, RunningEnvironment_StartAck, RunningEnvironment_Eval, RunningEnvironment_FSEventCreate, RunningEnvironment_FSEventRemove, RunningEnvironment_FSEventWrite, RunningEnvironment_CreateDir, RunningEnvironment_RemoveFile, RunningEnvironment_ListDir, RunningEnvironment_FileContent, RunningEnvironment_WriteFile, RunningEnvironment_DirContent, RunningEnvironment_GetFile, RunningEnvironment_Stdout, RunningEnvironment_Stderr, RunningEnvironment_ExecCmd, RunningEnvironment_KillCmd, RunningEnvironment_ListRunningCmds, RunningEnvironment_CmdOut, RunningEnvironment_CmdExit, RunningEnvironment_RunningCmds, RunningEnvironment_RunCode, RunningEnvironment_TermData, RunningEnvironment_TermStart, RunningEnvironment_TermStartAck, RunningEnvironment_TermResize, } from './RunningEnvironmentMessage';
export type { BaseCodeCell, CodeCell_Error, } from './CodeCellMessage';
export type { RunnerError, } from './RunnerErrorMessage';
export { ErrorCodes, ErrorFactory, } from './RunnerErrorMessage';

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

export interface BaseRunningEnvironment extends BaseMessage {
type: TRunningEnvironment.Start | TRunningEnvironment.StartAck | TRunningEnvironment.Eval | TRunningEnvironment.FSEventCreate | TRunningEnvironment.FSEventRemove | TRunningEnvironment.FSEventWrite | TRunningEnvironment.CreateDir | TRunningEnvironment.WriteFile | TRunningEnvironment.RemoveFile | TRunningEnvironment.ListDir | TRunningEnvironment.DirContent | TRunningEnvironment.FileContent | TRunningEnvironment.GetFile | TRunningEnvironment.Stdout | TRunningEnvironment.Stderr | TRunningEnvironment.ExecCmd | TRunningEnvironment.KillCmd | TRunningEnvironment.ListRunningCmds | TRunningEnvironment.CmdOut | TRunningEnvironment.CmdExit | TRunningEnvironment.RunningCmds | TRunningEnvironment.RunCode;
type: TRunningEnvironment.Start | TRunningEnvironment.StartAck | TRunningEnvironment.Eval | TRunningEnvironment.FSEventCreate | TRunningEnvironment.FSEventRemove | TRunningEnvironment.FSEventWrite | TRunningEnvironment.CreateDir | TRunningEnvironment.WriteFile | TRunningEnvironment.RemoveFile | TRunningEnvironment.ListDir | TRunningEnvironment.DirContent | TRunningEnvironment.FileContent | TRunningEnvironment.GetFile | TRunningEnvironment.Stdout | TRunningEnvironment.Stderr | TRunningEnvironment.ExecCmd | TRunningEnvironment.KillCmd | TRunningEnvironment.ListRunningCmds | TRunningEnvironment.CmdOut | TRunningEnvironment.CmdExit | TRunningEnvironment.RunningCmds | TRunningEnvironment.RunCode | TRunningEnvironment.TermData | TRunningEnvironment.TermStart | TRunningEnvironment.TermStartAck | TRunningEnvironment.TermResize;
payload: {

@@ -180,2 +180,35 @@ environmentID: string;

}
export interface RunningEnvironment_TermStart extends BaseRunningEnvironment {
type: TRunningEnvironment.TermStart;
payload: {
environmentID: string;
terminalID?: string;
messageID: string;
};
}
export interface RunningEnvironment_TermStartAck extends BaseRunningEnvironment {
type: TRunningEnvironment.TermStartAck;
payload: {
environmentID: string;
terminalID: string;
messageID: string;
};
}
export interface RunningEnvironment_TermData extends BaseRunningEnvironment {
type: TRunningEnvironment.TermData;
payload: {
environmentID: string;
terminalID: string;
data: string;
};
}
export interface RunningEnvironment_TermResize extends BaseRunningEnvironment {
type: TRunningEnvironment.TermResize;
payload: {
environmentID: string;
terminalID: string;
cols: number;
rows: number;
};
}
/**

@@ -182,0 +215,0 @@ * Received from remote Runner when an environments prints to stdout.

@@ -46,3 +46,19 @@ import { Filesystem } from './runningEnvironment/filesystem';

}
export interface TerminalSession {
sendData: (data: string) => void;
resize: ({ cols, rows }: {
cols: number;
rows: number;
}) => void;
destroy: () => void;
}
/**
* Methods for managing terminal sessions.
*
* This object is used internally by the `Terminal` component from Devbook UI package - https://github.com/devbookhq/ui#terminal.
*/
export interface Terminal {
createSession: (onData: (data: string) => void, activeTerminalID?: string) => Promise<TerminalSession>;
}
/**
* States of a {@link Devbook} connection to a VM.

@@ -75,5 +91,2 @@ */

private executionID;
private _sessionID?;
private get sessionID();
private set sessionID(value);
private _isDestroyed;

@@ -95,6 +108,7 @@ private get isDestroyed();

private get env();
readonly terminal: Terminal;
/**
* Use this for accessing and manipulating this `Devbook`'s VM's filesystem.
*/
get fs(): FS;
readonly fs: FS;
constructor(opts: {

@@ -122,8 +136,2 @@ /**

/**
* This function will be called when the URL for accessing this `Devbook`'s environment changes.
*
* You can assemble URL for any port by using the `getURL` function from the parameter.
*/
onURLChange?: (getURL: (port: number) => string | undefined) => void;
/**
* If this value is true then this `Devbook` will print detailed logs.

@@ -138,10 +146,2 @@ */

/**
* Compose the URL that can be used for connecting to a port on the environment defined in this `Devbook`'s constructor.
*
* @param port Number of the port that the URL should be connecting to.
* @returns URL address that allows you to connect to a specified port on this `Devbook`'s environment
* or `undefined` if this `Devbook` is not yet connected to a VM.
*/
getURL(port: number): string | undefined;
/**
* Run `command` in the VM.

@@ -153,3 +153,3 @@ *

*/
runCmd(command: string): void;
runCmd(command: string): Promise<void>;
/**

@@ -156,0 +156,0 @@ * Disconnect this `Devbook` from the VM.

@@ -14,3 +14,2 @@ import * as rws from '../common-ts/RunnerWebSocket';

status: SessionStatus;
sessionID?: string;
}) => void;

@@ -23,4 +22,7 @@ onEnvChange?: (env: RunningEnvironment) => void;

private get contextID();
private cmdExitSubscribers;
private fsWriteSubscribers;
private fileContentSubscribers;
private termDataSubscribers;
private termStartAckSubscribers;
readonly env: RunningEnvironment;

@@ -54,3 +56,25 @@ private readonly unsubscribeConnHandler;

command: string;
}): Promise<void>;
startTerminal({ terminalID }: {
terminalID?: string;
}): Promise<string>;
resizeTerminal({ terminalID, cols, rows }: {
terminalID: string;
cols: number;
rows: number;
}): void;
sendTerminalData({ terminalID, data }: {
terminalID: string;
data: string;
}): void;
onTerminalData({ terminalID, onData }: {
terminalID: string;
onData: (data: string) => void;
}): () => void;
private subscribeCmdExit;
private unsubscribeCmdExit;
private subscribeTermStartAck;
private unsubscribeTermStartAck;
private subscribeTermData;
private unsubscribeTermData;
private subscribeFileContent;

@@ -63,2 +87,4 @@ private unsubscribeFileContent;

private handleConnectionMessage;
private vmenv_handleTermStartAck;
private vmenv_handleTermData;
private vmenv_handleFSEventCreate;

@@ -65,0 +91,0 @@ private vmenv_handleFSEventRemove;

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

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

@@ -5,3 +5,5 @@ import EvaluationContext, { EvaluationContextOpts } from './evaluationContext';

private logger;
static config: Config;
static config: Config & {
logging?: boolean;
};
private static _obj;

@@ -8,0 +10,0 @@ static get obj(): Runner;

@@ -49,2 +49,18 @@ import { Env } from '../devbook';

}): void;
export { start, execCmd, writeFile, deleteFile, getFile, createDir, listDir, };
declare function termData(conn: WebSocketConnection, { environmentID, terminalID, data, }: {
environmentID: string;
terminalID: string;
data: string;
}): void;
declare function termResize(conn: WebSocketConnection, { environmentID, terminalID, cols, rows, }: {
environmentID: string;
terminalID: string;
cols: number;
rows: number;
}): void;
declare function termStart(conn: WebSocketConnection, { environmentID, terminalID, messageID, }: {
environmentID: string;
terminalID?: string;
messageID: string;
}): void;
export { start, execCmd, writeFile, deleteFile, getFile, createDir, listDir, termStart, termData, termResize, };
import * as rws from '../common-ts/RunnerWebSocket';
export interface Opts {
domain: string;
logging?: boolean;
}
interface Handler {
onMessage: (msg: rws.BaseMessage) => void;
onOpen: (sessionID: string) => void;
onOpen: () => void;
onClose: () => void;

@@ -21,3 +22,3 @@ }

get isConnecting(): boolean | undefined;
constructor({ domain }: Opts);
constructor({ domain, logging }: Opts);
subscribeHandler(handler: Handler): () => void;

@@ -24,0 +25,0 @@ connect(sessionID?: string): void;

export { useDevbook } from './react';
export type { Opts as UseDevbookOpts, } from './react';
export { Devbook, DevbookStatus, } from './core';
export type { Config, Env, } from './core';
export type { Config, Env, Terminal, TerminalSession, FS, } from './core';

@@ -1,16 +0,16 @@

!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self)["@devbookhq/sdk"]={},t.react)}(this,(function(t,e){"use strict";class n{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)}}
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self)["@devbookhq/sdk"]={},t.react)}(this,(function(t,e){"use strict";
/*! *****************************************************************************
Copyright (c) Microsoft Corporation.
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */function i(t,e,n,i){return new(n||(n=Promise))((function(s,o){function r(t){try{h(i.next(t))}catch(t){o(t)}}function a(t){try{h(i.throw(t))}catch(t){o(t)}}function h(t){var e;t.done?s(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(r,a)}h((i=i.apply(t,e||[])).next())}))}function s(t){return new Promise((e=>setTimeout(e,t)))}var o,r,a;!function(t){t.Error="Runner.Error"}(o||(o={})),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"}(r||(r={})),function(t){t.Error="CodeCell.Error"}(a||(a={}));const h={Runner:o,RunningEnvironment:r,CodeCell:a},l="dbk_sdk_session_id",c=2500;class d{constructor({domain:t}){this.logger=new n("WebSocketConnection"),this.handlers=[],this.url=`wss://${t}`}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 i(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 2.5s"),yield s(2500),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(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((t=>t.onMessage(n)))):this.logger.error("Runner error",n):this.logger.error('Message "type" field has unexpected value',n)}}var u,g;!function(t){t.Ok="Ok",t.Terminated="Terminated"}(u||(u={}));class m{constructor({id:t,url:e}){this.logger=new n("RunnerSession"),this.lastPing=new Date,this.id=t,this.url=e}ping(){return i(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===u.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"}(g||(g={}));class v{constructor({conn:t,domain:e}){this.logger=new n("SessionManager"),this.userActivity=Promise.resolve(),this.isGettingSessionActive=!1,this.status=g.Disconnected,this.conn=t,this.url=`https://${e}`,this.logger.log("Initialize"),this.getSession()}get cachedSessionID(){return sessionStorage.getItem(l)}set cachedSessionID(t){null===t?(this.logger.log("Cleared last sessionID"),sessionStorage.removeItem(l)):(this.logger.log(`Saved sessionID "${t}" as last sessionID`),sessionStorage.setItem(l,t))}stop(){var t;null===(t=this.startActivity)||void 0===t||t.call(this),this.userActivity=new Promise((t=>{this.startActivity=t})),this.reset()}start(){var t;null===(t=this.startActivity)||void 0===t||t.call(this)}reset(){this.logger.log("Reset"),this.status=g.Disconnected,this.cachedSessionID=null,this.conn.close(),this.session=void 0}getSession(){var t;return i(this,void 0,void 0,(function*(){if(!this.isGettingSessionActive)for(this.isGettingSessionActive=!0;;){this.status=g.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 2.5s",n.headers,i),yield s(c);continue}for(this.session=new m({id:i.sessionID,url:this.url}),this.logger.log(`Acquired session "${this.session.id}"`),this.cachedSessionID=this.session.id,this.status=g.Connected,this.conn.connect(this.session.id),this.logger.log(`Started pinging session "${this.session.id}"`);this.session;)try{yield this.userActivity,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=g.Disconnected,this.conn.close()}catch(t){this.logger.error("Failed to acquire Runner session. Will try again in 2.5s",t),yield s(c)}}}))}}function p(t,e){for(var n=0,i=t.length-1;i>=0;i--){var s=t[i];"."===s?t.splice(i,1):".."===s?(t.splice(i,1),n++):n&&(t.splice(i,1),n--)}if(e)for(;n--;n)t.unshift("..");return t}var f=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/,D=function(t){return f.exec(t).slice(1)};function y(){for(var t="",e=!1,n=arguments.length-1;n>=-1&&!e;n--){var i=n>=0?arguments[n]:"/";if("string"!=typeof i)throw new TypeError("Arguments to path.resolve must be strings");i&&(t=i+"/"+t,e="/"===i.charAt(0))}return(e?"/":"")+(t=p(w(t.split("/"),(function(t){return!!t})),!e).join("/"))||"."}function C(t){var e=S(t),n="/"===I(t,-1);return(t=p(w(t.split("/"),(function(t){return!!t})),!e).join("/"))||e||(t="."),t&&n&&(t+="/"),(e?"/":"")+t}function S(t){return"/"===t.charAt(0)}var b={extname:function(t){return D(t)[3]},basename:function(t,e){var n=D(t)[2];return e&&n.substr(-1*e.length)===e&&(n=n.substr(0,n.length-e.length)),n},dirname:function(t){var e=D(t),n=e[0],i=e[1];return n||i?(i&&(i=i.substr(0,i.length-1)),n+i):"."},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=y(t).substr(1),e=y(e).substr(1);for(var i=n(t.split("/")),s=n(e.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 t=Array.prototype.slice.call(arguments,0);return C(w(t,(function(t,e){if("string"!=typeof t)throw new TypeError("Arguments to path.join must be strings");return t})).join("/"))},isAbsolute:S,normalize:C,resolve:y};function w(t,e){if(t.filter)return t.filter(e);for(var n=[],i=0;i<t.length;i++)e(t[i],i,t)&&n.push(t[i]);return n}var E,I="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 R{get level(){return b.normalize(this.path).split(b.sep).length-1}}function k(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 F extends R{constructor({name:t,parent:e,onAddItem:n}){super(),this.children=[],this.name=t,this.parent=e,this.addItemHandler=n,this.path=b.join(this.parent.path,this.name)}removeChildNode(t){this.children=this.children.filter((e=>e!==t))}serialize(t,e,n){const i=this.children.map((i=>i.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:k(i)}}}class _ extends R{constructor({name:t,parent:e}){super(),this.name=t,this.parent=e,this.path=b.join(this.parent.path,this.name)}serialize(){return{type:"File",key:this.path,title:this.name,isLeaf:!0}}}class P extends R{constructor({parent:t,forNode:e,onConfirm:n,onBlur:i}){super(),this.name="name-prompt",this.parent=t,this.forNode=e,this.path=b.join(t.path,this.name),this.onConfirm=n,this.onBlur=i}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 x extends R{constructor({onAddItem:t}){super(),this.name="/",this.path="/",this.parent=void 0,this.children=[],this.addItemHandler=t}serialize(t,e,n){const i=this.children.map((i=>i.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:k(i)}}}class L extends R{constructor({parent:t}){super(),this.name="empty-node",this.parent=t,this.path=b.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 n("Filesystem"),this.root=new x({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 x||n instanceof F))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 i;i="Dir"===e.type?new F({name:e.name,parent:n,onAddItem:({event:t,dir:e,type:n})=>this.showPrompt({event:t,parent:e,type:n})}):new _({name:e.name,parent:n}),1===n.children.length&&n.children[0]instanceof L?n.children=[i]:n.children.push(i),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 x||n instanceof F))throw new Error(`Node at '${t}' is not a directory or root node`);const i=n.children.length;n.children=n.children.filter((t=>t.name!==e.name));i!==n.children.length?(0===n.children.length&&(n.children=[new L({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 x||t instanceof F))throw new Error(`Node at '${e.dirPath}' is not a directory or a root node`);const n=t.children.find((t=>t instanceof P));if(e.content.length){const n=[];for(const i of e.content){let e;e="Dir"===i.type?new F({name:i.name,parent:t,onAddItem:({event:t,dir:e,type:n})=>this.showPrompt({event:t,parent:e,type:n})}):new _({name:i.name,parent:t}),n.push(e)}t.children=n}else t.children=[new L({parent:t})];n&&t.children.push(n)}this.notifyOnDirsChangeLs({dirPaths:t.map((t=>t.dirPath))})}showPrompt(t){const{event:e,parent:n,type:i}=t;if(this.logger.log("Show prompt",{parent:n,type:i}),n.children.some((t=>t instanceof P)))return;e.preventDefault();const s=new P({parent:n,forNode:i,onConfirm:((t,e)=>{if(this.logger.log("Prompt confirm",{prompt:t,name:e}),!e)return;const n=t.parent.path,s=b.join(t.parent.path,e);this.removeFromParent(t),this.notifyOnDirsChangeLs({dirPaths:[n]}),this.notifyOnNewItemConfirmLs({fullPath:s,name:e,type:i})}).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(s),this.notifyOnDirsChangeLs({dirPaths:[s.parent.path]}),this.notifyOnShowPromptLs({dirPath:s.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 i of t.children)i instanceof F?this.print(i,e+1):console.log(n+" "+i.path,`(${i.name})`)}find(t,e=this.root){if(this.logger.log("Find (recursion)",{currentPath:e.path,targetPath:t}),t=b.normalize(t),e.path===t)return e;const n=t.split(b.sep).length-1;if(!(e.level>n)&&(e instanceof x||e instanceof F))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 x||e instanceof F))throw new Error("Parent is not a dir or root");const n=new F({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(b.sep);let n,i="/";for(const t of e)if(i=b.join(i,t),!this.find(i)){const e=b.dirname(i);n=this.mkDir({parentPath:e,name:t})}return n}removeFromParent(t){const{parent:e}=t;(e instanceof x||e instanceof F)&&(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 N(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"}(E||(E={}));class A{constructor(t,e){this.contextID=t,this.templateID=e,this.output=[],this.filesystem=new O,this.isReady=!1,this.id=`${t}_${N(e)}`}restart(){this.output=[],this.isReady=!1,this.filesystem.setDirsContent([{dirPath:"/",content:[]}])}logOutput(t,e){this.output=[...this.output,{message:t,source:e}]}}function $(t,{environmentID:e,templateID:n}){const i={type:h.RunningEnvironment.Start,payload:{environmentID:e,templateID:n}};t.send(i)}class M{constructor(t){var e,i;this.opts=t,this.fsWriteSubscribers=[],this.fileContentSubscribers=[],this.logger=new n(`EvaluationContext [${t.templateID}]`,t.debug),this.env=new A(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(),$(this.opts.conn,{environmentID:this.env.id,templateID:this.env.templateID}),null===(i=(e=this.opts).onEnvChange)||void 0===i||i.call(e,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:t}){return i(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)})),i=n=>{n.path.endsWith(t)&&e(n.content)};this.subscribeFileContent(i),function(t,{environmentID:e,path:n}){const i={type:h.RunningEnvironment.GetFile,payload:{environmentID:e,path:n}};t.send(i)}(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(i)}}))}deleteFile({path:t}){this.logger.log("Delete file",{filepath:t}),function(t,{environmentID:e,path:n}){const i={type:h.RunningEnvironment.RemoveFile,payload:{environmentID:e,path:n}};t.send(i)}(this.opts.conn,{environmentID:this.env.id,path:t})}updateFile({path:t,content:e}){return i(this,void 0,void 0,(function*(){let n;this.logger.log("Update file",{filepath:t});const i=new Promise(((t,e)=>{n=t,setTimeout((()=>{e("Timeout")}),1e4)})),s=e=>{e.path.endsWith(t)&&n()};this.subscribeFSWrite(s),function(t,{environmentID:e,path:n,content:i}){const s={type:h.RunningEnvironment.WriteFile,payload:{environmentID:e,path:n,content:i}};t.send(s)}(this.opts.conn,{environmentID:this.env.id,path:t,content:e});try{yield i}catch(e){throw new Error(`File ${t} not written to VM: ${e}`)}finally{this.unsubscribeFSWrite(s)}}))}createDir({path:t}){this.logger.log("Create dir",{filepath:t}),function(t,{environmentID:e,path:n}){const i={type:h.RunningEnvironment.CreateDir,payload:{environmentID:e,path:n}};t.send(i)}(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 i={type:h.RunningEnvironment.ListDir,payload:{environmentID:e,path:n}};t.send(i)}(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:i}){const s={type:h.RunningEnvironment.ExecCmd,payload:{environmentID:e,executionID:n,command:i}};t.send(s)}(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:g.Connecting})}handleConnectionClose(){var t,e;null===(e=(t=this.opts).onSessionChange)||void 0===e||e.call(t,{status:g.Connecting})}handleConnectionMessage(t){switch(this.logger.log("Handling message from remote Runner",{message:t}),t.type){case h.RunningEnvironment.StartAck:{const e=t;this.vmenv_handleStartAck(e.payload);break}case h.RunningEnvironment.CmdOut:{const e=t;this.vmenv_handleCmdOut(e.payload);break}case h.RunningEnvironment.CmdExit:{const e=t;this.vmenv_handleCmdExit(e.payload);break}case h.RunningEnvironment.FSEventWrite:{const e=t;this.vmenv_handleFSEventWrite(e.payload);break}case h.RunningEnvironment.FileContent:{const e=t;this.vmenv_handleFileContent(e.payload);break}case h.RunningEnvironment.FSEventCreate:{const e=t;this.vmenv_handleFSEventCreate(e.payload);break}case h.RunningEnvironment.FSEventRemove:{const e=t;this.vmenv_handleFSEventRemove(e.payload);break}case h.RunningEnvironment.DirContent:{const e=t;this.vmenv_handleDirContent(e.payload);break}case h.RunningEnvironment.Stderr:{const e=t;this.vmenv_handleStderr(e.payload);break}case h.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=b.basename(t.path),n=b.dirname(t.path),i="Directory"===t.type?"Dir":"File";this.env.filesystem.addNodeToDir(n,{name:e,type:i})}vmenv_handleFSEventRemove(t){this.logger.log('[vmenv] Handling "FSEventRemove"',{payload:t});const e=b.basename(t.path),n=b.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=b.basename(n.path),i="Directory"===n.type?"Dir":"File";e.push({name:t,type:i})}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,i,s;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),null===(s=(i=this.opts).onSessionChange)||void 0===s||s.call(i,{status:g.Connected,sessionID:this.opts.conn.sessionID})}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,E.Stderr)}vmenv_handleStdout(t){this.logger.log('[vmenv] Handling "Stdout"',t),this.env.logOutput(t.message,E.Stdout)}}class j{constructor(){this.logger=new n("Runner"),this.conn=new d({domain:j.config.domain}),this.sessManager=new v({conn:this.conn,domain:j.config.domain})}static get obj(){if(!j.config)throw new Error("Config not set");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(t){return new M(Object.assign(Object.assign({},t),{conn:this.conn}))}__internal__start(){this.sessManager.start()}__internal__stop(){this.sessManager.stop()}__debug__loadNewSession(){this.logger.log("__debug__loadNewSession"),this.sessManager.reset()}}const W=(H="1234567890abcdefghijklmnopqrstuvwxyz",T=6,()=>{let t="",e=T;for(;e--;)t+=H[Math.random()*H.length|0];return t});var H,T,z;t.DevbookStatus=void 0,(z=t.DevbookStatus||(t.DevbookStatus={})).Disconnected="Disconnected",z.Connecting="Connecting",z.Connected="Connected";class G{constructor(e){if(this.opts=e,this.contextID="default",this.executionID=W(),this._isDestroyed=!1,this._isEnvReady=!1,this._sessionStatus=g.Disconnected,this._status=t.DevbookStatus.Disconnected,!e.config)throw new Error("Missing Devbook config");const n=this.getURL.bind(this),i=()=>this.opts.env,s=()=>this.executionID,o=t=>this.isEnvReady=t,r=t=>this.sessionStatus=t,a=t=>this.sessionID=t;j.config=this.opts.config,this.context=j.obj.createContext({debug:e.debug,templateID:e.env,contextID:this.contextID,onEnvChange(t){var s;t.templateID===i()&&(o(t.isReady),null===(s=e.onURLChange)||void 0===s||s.call(e,n))},onSessionChange({status:t,sessionID:i}){var s;a(i),r(t),null===(s=e.onURLChange)||void 0===s||s.call(e,n)},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(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(e){if(this.status===t.DevbookStatus.Connected&&this.sessionID&&this.env.isReady)return`https://${e}-${this.env.id}-${this.sessionID}.o.usedevbook.com`}runCmd(e){if(this.status!==t.DevbookStatus.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}__internal__start(){j.obj.__internal__start()}__internal__stop(){j.obj.__internal__stop()}listDir(e){if(this.status!==t.DevbookStatus.Connected)throw new Error("Not connected to the VM yet.");return this.context.listDir({path:e})}createDir(e){if(this.status!==t.DevbookStatus.Connected)throw new Error("Not connected to the VM yet.");return this.context.createDir({path:e})}deleteFile(e){if(this.status!==t.DevbookStatus.Connected)throw new Error("Not connected to the VM yet.");return this.context.deleteFile({path:e})}getFile(e){if(this.status!==t.DevbookStatus.Connected)throw new Error("Not connected to the VM yet.");return this.context.getFile({path:e})}writeFile(e,n){if(this.status!==t.DevbookStatus.Connected)throw new Error("Not connected to the VM yet.");return this.context.updateFile({path:e,content:n})}updateStatus(){if(this.isDestroyed)return void(this.status!==t.DevbookStatus.Disconnected&&(this.status=t.DevbookStatus.Disconnected));let e;switch(this.sessionStatus){case g.Disconnected:e=t.DevbookStatus.Disconnected;break;case g.Connecting:e=t.DevbookStatus.Connecting;break;case g.Connected:if(!this.isEnvReady){e=t.DevbookStatus.Connecting;break}e=t.DevbookStatus.Connected}this.status=e}}t.Devbook=G,t.useDevbook=function({env:n,debug:i,config:s}){const[o,r]=e.useState(),[a,h]=e.useState(t.DevbookStatus.Disconnected),[l,c]=e.useState([]),[d,u]=e.useState([]),g=e.useCallback((t=>{o&&(u([]),c([]),o.runCmd(t))}),[o]);return e.useEffect((function(){const t=new G({debug:i,env:n,onStatusChange(t){h(t)},onStderr(t){c((e=>[...e,t]))},onStdout(t){u((e=>[...e,t]))},config:s});return u([]),c([]),r(t),()=>{t.destroy()}}),[n,i,s]),{stderr:l,stdout:d,runCmd:g,status:a,fs:null==o?void 0:o.fs}},Object.defineProperty(t,"__esModule",{value:!0})}));
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */function n(t,e,n,i){return new(n||(n=Promise))((function(s,o){function r(t){try{h(i.next(t))}catch(t){o(t)}}function a(t){try{h(i.throw(t))}catch(t){o(t)}}function h(t){var e;t.done?s(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(r,a)}h((i=i.apply(t,e||[])).next())}))}function i(t){return e="1234567890abcdefghijklmnopqrstuvwxyz",n=t,()=>{let t="",i=n;for(;i--;)t+=e[Math.random()*e.length|0];return t};var e,n}class s{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)}}function o(t){return new Promise((e=>setTimeout(e,t)))}var r,a,h;!function(t){t.Error="Runner.Error"}(r||(r={})),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.TermData="RunningEnvironment.TermData",t.TermResize="RunningEnvironment.TermResize",t.TermStart="RunningEnvironment.TermStart",t.TermStartAck="RunningEnvironment.TermStartAck",t.RunCode="RunningEnvironment.Run"}(a||(a={})),function(t){t.Error="CodeCell.Error"}(h||(h={}));const l={Runner:r,RunningEnvironment:a,CodeCell:h},c="dbk_sdk_session_id",d=2500;class u{constructor({domain:t,logging:e}){this.handlers=[],this.url=`wss://${t}`,this.logger=new s("WebSocketConnection",e)}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.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(){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()))}_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 2.5s"),yield o(2500),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(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((t=>t.onMessage(n)))):this.logger.error("Runner error",n):this.logger.error('Message "type" field has unexpected value',n)}}var m,g;!function(t){t.Ok="Ok",t.Terminated="Terminated"}(m||(m={}));class v{constructor({id:t,url:e}){this.logger=new s("RunnerSession"),this.lastPing=new Date,this.id=t,this.url=e}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===m.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"}(g||(g={}));class p{constructor({conn:t,domain:e}){this.logger=new s("SessionManager"),this.userActivity=Promise.resolve(),this.isGettingSessionActive=!1,this.status=g.Disconnected,this.conn=t,this.url=`https://${e}`,this.logger.log("Initialize"),this.getSession()}get cachedSessionID(){return sessionStorage.getItem(c)}set cachedSessionID(t){null===t?(this.logger.log("Cleared last sessionID"),sessionStorage.removeItem(c)):(this.logger.log(`Saved sessionID "${t}" as last sessionID`),sessionStorage.setItem(c,t))}stop(){var t;null===(t=this.startActivity)||void 0===t||t.call(this),this.userActivity=new Promise((t=>{this.startActivity=t})),this.reset()}start(){var t;null===(t=this.startActivity)||void 0===t||t.call(this)}reset(){this.logger.log("Reset"),this.status=g.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=g.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 2.5s",n.headers,i),yield o(d);continue}for(this.session=new v({id:i.sessionID,url:this.url}),this.logger.log(`Acquired session "${this.session.id}"`),this.cachedSessionID=this.session.id,this.status=g.Connected,this.conn.connect(this.session.id),this.logger.log(`Started pinging session "${this.session.id}"`);this.session;)try{yield this.userActivity,yield this.session.ping(),yield o(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=g.Disconnected,this.conn.close()}catch(t){this.logger.error("Failed to acquire Runner session. Will try again in 2.5s",t),yield o(d)}}}))}}function f(t,e){for(var n=0,i=t.length-1;i>=0;i--){var s=t[i];"."===s?t.splice(i,1):".."===s?(t.splice(i,1),n++):n&&(t.splice(i,1),n--)}if(e)for(;n--;n)t.unshift("..");return t}var D=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/,y=function(t){return D.exec(t).slice(1)};function b(){for(var t="",e=!1,n=arguments.length-1;n>=-1&&!e;n--){var i=n>=0?arguments[n]:"/";if("string"!=typeof i)throw new TypeError("Arguments to path.resolve must be strings");i&&(t=i+"/"+t,e="/"===i.charAt(0))}return(e?"/":"")+(t=f(w(t.split("/"),(function(t){return!!t})),!e).join("/"))||"."}function S(t){var e=C(t),n="/"===R(t,-1);return(t=f(w(t.split("/"),(function(t){return!!t})),!e).join("/"))||e||(t="."),t&&n&&(t+="/"),(e?"/":"")+t}function C(t){return"/"===t.charAt(0)}var E={extname:function(t){return y(t)[3]},basename:function(t,e){var n=y(t)[2];return e&&n.substr(-1*e.length)===e&&(n=n.substr(0,n.length-e.length)),n},dirname:function(t){var e=y(t),n=e[0],i=e[1];return n||i?(i&&(i=i.substr(0,i.length-1)),n+i):"."},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=b(t).substr(1),e=b(e).substr(1);for(var i=n(t.split("/")),s=n(e.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 t=Array.prototype.slice.call(arguments,0);return S(w(t,(function(t,e){if("string"!=typeof t)throw new TypeError("Arguments to path.join must be strings");return t})).join("/"))},isAbsolute:C,normalize:S,resolve:b};function w(t,e){if(t.filter)return t.filter(e);for(var n=[],i=0;i<t.length;i++)e(t[i],i,t)&&n.push(t[i]);return n}var I,R="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 k{get level(){return E.normalize(this.path).split(E.sep).length-1}}function F(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 x extends k{constructor({name:t,parent:e,onAddItem:n}){super(),this.children=[],this.name=t,this.parent=e,this.addItemHandler=n,this.path=E.join(this.parent.path,this.name)}removeChildNode(t){this.children=this.children.filter((e=>e!==t))}serialize(t,e,n){const i=this.children.map((i=>i.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:F(i)}}}class _ extends k{constructor({name:t,parent:e}){super(),this.name=t,this.parent=e,this.path=E.join(this.parent.path,this.name)}serialize(){return{type:"File",key:this.path,title:this.name,isLeaf:!0}}}class P extends k{constructor({parent:t,forNode:e,onConfirm:n,onBlur:i}){super(),this.name="name-prompt",this.parent=t,this.forNode=e,this.path=E.join(t.path,this.name),this.onConfirm=n,this.onBlur=i}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 O extends k{constructor({onAddItem:t}){super(),this.name="/",this.path="/",this.parent=void 0,this.children=[],this.addItemHandler=t}serialize(t,e,n){const i=this.children.map((i=>i.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:F(i)}}}class T extends k{constructor({parent:t}){super(),this.name="empty-node",this.parent=t,this.path=E.join(this.parent.path,this.name)}serialize(){return{type:"Empty",key:this.path,title:"Empty Directory",isLeaf:!0,disabled:!0}}}class A{constructor(){this.logger=new s("Filesystem"),this.root=new O({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 O||n instanceof x))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 i;i="Dir"===e.type?new x({name:e.name,parent:n,onAddItem:({event:t,dir:e,type:n})=>this.showPrompt({event:t,parent:e,type:n})}):new _({name:e.name,parent:n}),1===n.children.length&&n.children[0]instanceof T?n.children=[i]:n.children.push(i),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 O||n instanceof x))throw new Error(`Node at '${t}' is not a directory or root node`);const i=n.children.length;n.children=n.children.filter((t=>t.name!==e.name));i!==n.children.length?(0===n.children.length&&(n.children=[new T({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 O||t instanceof x))throw new Error(`Node at '${e.dirPath}' is not a directory or a root node`);const n=t.children.find((t=>t instanceof P));if(e.content.length){const n=[];for(const i of e.content){let e;e="Dir"===i.type?new x({name:i.name,parent:t,onAddItem:({event:t,dir:e,type:n})=>this.showPrompt({event:t,parent:e,type:n})}):new _({name:i.name,parent:t}),n.push(e)}t.children=n}else t.children=[new T({parent:t})];n&&t.children.push(n)}this.notifyOnDirsChangeLs({dirPaths:t.map((t=>t.dirPath))})}showPrompt(t){const{event:e,parent:n,type:i}=t;if(this.logger.log("Show prompt",{parent:n,type:i}),n.children.some((t=>t instanceof P)))return;e.preventDefault();const s=new P({parent:n,forNode:i,onConfirm:((t,e)=>{if(this.logger.log("Prompt confirm",{prompt:t,name:e}),!e)return;const n=t.parent.path,s=E.join(t.parent.path,e);this.removeFromParent(t),this.notifyOnDirsChangeLs({dirPaths:[n]}),this.notifyOnNewItemConfirmLs({fullPath:s,name:e,type:i})}).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(s),this.notifyOnDirsChangeLs({dirPaths:[s.parent.path]}),this.notifyOnShowPromptLs({dirPath:s.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 i of t.children)i instanceof x?this.print(i,e+1):console.log(n+" "+i.path,`(${i.name})`)}find(t,e=this.root){if(this.logger.log("Find (recursion)",{currentPath:e.path,targetPath:t}),t=E.normalize(t),e.path===t)return e;const n=t.split(E.sep).length-1;if(!(e.level>n)&&(e instanceof O||e instanceof x))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 O||e instanceof x))throw new Error("Parent is not a dir or root");const n=new x({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(E.sep);let n,i="/";for(const t of e)if(i=E.join(i,t),!this.find(i)){const e=E.dirname(i);n=this.mkDir({parentPath:e,name:t})}return n}removeFromParent(t){const{parent:e}=t;(e instanceof O||e instanceof x)&&(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 N(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"}(I||(I={}));class L{constructor(t,e){this.contextID=t,this.templateID=e,this.output=[],this.filesystem=new A,this.isReady=!1,this.id=`${t}_${N(e)}`}restart(){this.output=[],this.isReady=!1,this.filesystem.setDirsContent([{dirPath:"/",content:[]}])}logOutput(t,e){this.output=[...this.output,{message:t,source:e}]}}function $(t,{environmentID:e,templateID:n}){const i={type:l.RunningEnvironment.Start,payload:{environmentID:e,templateID:n}};t.send(i)}const M=i(6);class j{constructor(t){var e,n;this.opts=t,this.cmdExitSubscribers=[],this.fsWriteSubscribers=[],this.fileContentSubscribers=[],this.termDataSubscribers=[],this.termStartAckSubscribers=[],this.logger=new s(`EvaluationContext [${t.templateID}]`,t.debug),this.env=new L(this.contextID,t.templateID);this.unsubscribeConnHandler=this.opts.conn.subscribeHandler({onOpen:()=>this.handleConnectionOpen(),onMessage:t=>this.handleConnectionMessage(t),onClose:()=>this.handleConnectionClose()}),this.opts.conn.isOpen&&this.handleConnectionOpen(),this.opts.conn.isClosed&&this.handleConnectionClose(),$(this.opts.conn,{environmentID:this.env.id,templateID:this.env.templateID}),null===(n=(e=this.opts).onEnvChange)||void 0===n||n.call(e,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: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)})),i=n=>{n.path.endsWith(t)&&e(n.content)};this.subscribeFileContent(i),function(t,{environmentID:e,path:n}){const i={type:l.RunningEnvironment.GetFile,payload:{environmentID:e,path:n}};t.send(i)}(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(i)}}))}deleteFile({path:t}){this.logger.log("Delete file",{filepath:t}),function(t,{environmentID:e,path:n}){const i={type:l.RunningEnvironment.RemoveFile,payload:{environmentID:e,path:n}};t.send(i)}(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 i=new Promise(((t,e)=>{n=t,setTimeout((()=>{e("Timeout")}),1e4)})),s=e=>{e.path.endsWith(t)&&n()};this.subscribeFSWrite(s),function(t,{environmentID:e,path:n,content:i}){const s={type:l.RunningEnvironment.WriteFile,payload:{environmentID:e,path:n,content:i}};t.send(s)}(this.opts.conn,{environmentID:this.env.id,path:t,content:e});try{yield i}catch(e){throw new Error(`File ${t} not written to VM: ${e}`)}finally{this.unsubscribeFSWrite(s)}}))}createDir({path:t}){this.logger.log("Create dir",{filepath:t}),function(t,{environmentID:e,path:n}){const i={type:l.RunningEnvironment.CreateDir,payload:{environmentID:e,path:n}};t.send(i)}(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 i={type:l.RunningEnvironment.ListDir,payload:{environmentID:e,path:n}};t.send(i)}(this.opts.conn,{environmentID:this.env.id,path:t})}executeCommand({executionID:t,command:e}){return n(this,void 0,void 0,(function*(){let n;this.logger.log("Execute shell command",{executionID:t,command:e});let i=!1;const s=new Promise(((t,e)=>{n=t,setTimeout((()=>{i||e("Timeout")}),1e4)})),o=e=>{e.executionID===t&&(n(t),i=!0)};this.subscribeCmdExit(o),function(t,{environmentID:e,executionID:n,command:i}){const s={type:l.RunningEnvironment.ExecCmd,payload:{environmentID:e,executionID:n,command:i}};t.send(s)}(this.opts.conn,{environmentID:this.env.id,executionID:t,command:e});try{yield s}catch(t){throw new Error(`Can't exit cmd: ${t}`)}finally{this.unsubscribeCmdExit(o)}}))}startTerminal({terminalID:t}){return n(this,void 0,void 0,(function*(){this.logger.log("Start terminal",{terminalID:t});const e=M();let n,i=!1;const s=new Promise(((t,e)=>{n=t,setTimeout((()=>{i||e("Timeout")}),1e4)})),o=t=>{t.messageID===e&&(n(t.terminalID),i=!0)};this.subscribeTermStartAck(o),function(t,{environmentID:e,terminalID:n,messageID:i}){const s={type:l.RunningEnvironment.TermStart,payload:{environmentID:e,terminalID:n,messageID:i}};t.send(s)}(this.opts.conn,{environmentID:this.env.id,terminalID:t,messageID:e});try{return yield s}catch(t){throw new Error(`Can't start terminal session: ${t}`)}finally{this.unsubscribeTermStartAck(o)}}))}resizeTerminal({terminalID:t,cols:e,rows:n}){this.logger.log("Resize terminal",{terminalID:t,cols:e,rows:n}),function(t,{environmentID:e,terminalID:n,cols:i,rows:s}){const o={type:l.RunningEnvironment.TermResize,payload:{environmentID:e,terminalID:n,cols:i,rows:s}};t.send(o)}(this.opts.conn,{environmentID:this.env.id,terminalID:t,cols:e,rows:n})}sendTerminalData({terminalID:t,data:e}){this.logger.log("Send terminal data",{terminalID:t}),function(t,{environmentID:e,terminalID:n,data:i}){const s={type:l.RunningEnvironment.TermData,payload:{environmentID:e,terminalID:n,data:i}};t.send(s)}(this.opts.conn,{environmentID:this.env.id,terminalID:t,data:e})}onTerminalData({terminalID:t,onData:e}){const n=n=>{n.terminalID===t&&e(n.data)};return this.subscribeTermData(n),()=>this.unsubscribeTermData(n)}subscribeCmdExit(t){this.cmdExitSubscribers.push(t)}unsubscribeCmdExit(t){const e=this.cmdExitSubscribers.indexOf(t);e>-1&&this.cmdExitSubscribers.splice(e,1)}subscribeTermStartAck(t){this.termStartAckSubscribers.push(t)}unsubscribeTermStartAck(t){const e=this.termStartAckSubscribers.indexOf(t);e>-1&&this.termStartAckSubscribers.splice(e,1)}subscribeTermData(t){this.termDataSubscribers.push(t)}unsubscribeTermData(t){const e=this.termDataSubscribers.indexOf(t);e>-1&&this.termDataSubscribers.splice(e,1)}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(){var t,e;this.restart(),null===(e=(t=this.opts).onSessionChange)||void 0===e||e.call(t,{status:g.Connecting})}handleConnectionClose(){var t,e;null===(e=(t=this.opts).onSessionChange)||void 0===e||e.call(t,{status:g.Connecting})}handleConnectionMessage(t){switch(this.logger.log("Handling message from remote Runner",{message:t}),t.type){case l.RunningEnvironment.StartAck:{const e=t;this.vmenv_handleStartAck(e.payload);break}case l.RunningEnvironment.CmdOut:{const e=t;this.vmenv_handleCmdOut(e.payload);break}case l.RunningEnvironment.CmdExit:{const e=t;this.vmenv_handleCmdExit(e.payload);break}case l.RunningEnvironment.FSEventWrite:{const e=t;this.vmenv_handleFSEventWrite(e.payload);break}case l.RunningEnvironment.FileContent:{const e=t;this.vmenv_handleFileContent(e.payload);break}case l.RunningEnvironment.FSEventCreate:{const e=t;this.vmenv_handleFSEventCreate(e.payload);break}case l.RunningEnvironment.FSEventRemove:{const e=t;this.vmenv_handleFSEventRemove(e.payload);break}case l.RunningEnvironment.DirContent:{const e=t;this.vmenv_handleDirContent(e.payload);break}case l.RunningEnvironment.Stderr:{const e=t;this.vmenv_handleStderr(e.payload);break}case l.RunningEnvironment.Stdout:{const e=t;this.vmenv_handleStdout(e.payload);break}case l.RunningEnvironment.TermData:{const e=t;this.vmenv_handleTermData(e.payload);break}case l.RunningEnvironment.TermStartAck:{const e=t;this.vmenv_handleTermStartAck(e.payload);break}default:this.logger.warn("Unknown message type",{message:t})}}vmenv_handleTermStartAck(t){this.logger.log('[vmenv] Handling "TermStartAck"',t),this.termStartAckSubscribers.forEach((e=>e(t)))}vmenv_handleTermData(t){this.logger.log('[vmenv] Handling "TermData"',t),this.termDataSubscribers.forEach((e=>e(t)))}vmenv_handleFSEventCreate(t){this.logger.log('[vmenv] Handling "FSEventCreate"',t);const e=E.basename(t.path),n=E.dirname(t.path),i="Directory"===t.type?"Dir":"File";this.env.filesystem.addNodeToDir(n,{name:e,type:i})}vmenv_handleFSEventRemove(t){this.logger.log('[vmenv] Handling "FSEventRemove"',{payload:t});const e=E.basename(t.path),n=E.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=E.basename(n.path),i="Directory"===n.type?"Dir":"File";e.push({name:t,type:i})}this.env.filesystem.setDirsContent([{dirPath:t.dirPath,content:e}])}vmenv_handleCmdExit(t){var e,n;this.logger.log('[vmenv] Handling "CmdExit"',t),this.cmdExitSubscribers.forEach((e=>e(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,i,s;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),null===(s=(i=this.opts).onSessionChange)||void 0===s||s.call(i,{status:g.Connected})}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,I.Stderr)}vmenv_handleStdout(t){this.logger.log('[vmenv] Handling "Stdout"',t),this.env.logOutput(t.message,I.Stdout)}}class W{constructor(){this.logger=new s("Runner"),this.conn=new u({domain:W.config.domain,logging:W.config.logging}),this.sessManager=new p({conn:this.conn,domain:W.config.domain})}static get obj(){if(!W.config)throw new Error("Config not set");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(t){return new j(Object.assign(Object.assign({},t),{conn:this.conn}))}__internal__start(){this.sessManager.start()}__internal__stop(){this.sessManager.stop()}__debug__loadNewSession(){this.logger.log("__debug__loadNewSession"),this.sessManager.reset()}}const z=i(6);var H;t.DevbookStatus=void 0,(H=t.DevbookStatus||(t.DevbookStatus={})).Disconnected="Disconnected",H.Connecting="Connecting",H.Connected="Connected";class G{constructor(e){if(this.opts=e,this.contextID="default",this.executionID=z(),this._isDestroyed=!1,this._isEnvReady=!1,this._sessionStatus=g.Disconnected,this._status=t.DevbookStatus.Disconnected,!e.config)throw new Error("Missing Devbook config");const i=()=>this.opts.env,s=()=>this.executionID,o=t=>this.isEnvReady=t,r=t=>this.sessionStatus=t;W.config=Object.assign(Object.assign({},this.opts.config),{logging:e.debug}),this.context=W.obj.createContext({debug:e.debug,templateID:e.env,contextID:this.contextID,onEnvChange(t){t.templateID===i()&&o(t.isReady)},onSessionChange({status:t}){r(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)))}}),this.fs={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:this.env.filesystem.addListener.bind(this.env.filesystem),removeListener:this.env.filesystem.removeListener.bind(this.env.filesystem),serialize:this.env.filesystem.serialize.bind(this.env.filesystem)},this.terminal={createSession:(t,e)=>n(this,void 0,void 0,(function*(){const n=yield this.context.startTerminal({terminalID:e}),i=this.context.onTerminalData({onData:t,terminalID:n});return{destroy:()=>{i()},sendData:t=>{this.context.sendTerminalData({terminalID:n,data:t})},resize:({cols:t,rows:e})=>{this.context.resizeTerminal({terminalID:n,cols:t,rows:e})}}}))}}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}runCmd(e){if(this.status!==t.DevbookStatus.Connected)throw new Error("Not connected to the VM yet.");return this.executionID=z(),this.context.executeCommand({executionID:this.executionID,command:e})}destroy(){this.context.destroy(),this.isDestroyed=!0}__internal__start(){W.obj.__internal__start()}__internal__stop(){W.obj.__internal__stop()}listDir(e){if(this.status!==t.DevbookStatus.Connected)throw new Error("Not connected to the VM yet.");return this.context.listDir({path:e})}createDir(e){if(this.status!==t.DevbookStatus.Connected)throw new Error("Not connected to the VM yet.");return this.context.createDir({path:e})}deleteFile(e){if(this.status!==t.DevbookStatus.Connected)throw new Error("Not connected to the VM yet.");return this.context.deleteFile({path:e})}getFile(e){if(this.status!==t.DevbookStatus.Connected)throw new Error("Not connected to the VM yet.");return this.context.getFile({path:e})}writeFile(e,n){if(this.status!==t.DevbookStatus.Connected)throw new Error("Not connected to the VM yet.");return this.context.updateFile({path:e,content:n})}updateStatus(){if(this.isDestroyed)return void(this.status!==t.DevbookStatus.Disconnected&&(this.status=t.DevbookStatus.Disconnected));let e;switch(this.sessionStatus){case g.Disconnected:e=t.DevbookStatus.Disconnected;break;case g.Connecting:e=t.DevbookStatus.Connecting;break;case g.Connected:if(!this.isEnvReady){e=t.DevbookStatus.Connecting;break}e=t.DevbookStatus.Connected}this.status=e}}t.Devbook=G,t.useDevbook=function({env:i,debug:s,config:o}){const[r,a]=e.useState(),[h,l]=e.useState(t.DevbookStatus.Disconnected),[c,d]=e.useState([]),[u,m]=e.useState([]),g=e.useCallback((t=>n(this,void 0,void 0,(function*(){r&&(m([]),d([]),r.runCmd(t))}))),[r]);return e.useEffect((function(){const t=new G({debug:s,env:i,config:{domain:o.domain},onStatusChange(t){l(t)},onStderr(t){d((e=>[...e,t]))},onStdout(t){m((e=>[...e,t]))}});return m([]),d([]),a(t),()=>{t.destroy()}}),[i,s,o.domain]),{stderr:c,stdout:u,runCmd:g,status:h,fs:null==r?void 0:r.fs,terminal:null==r?void 0:r.terminal}},Object.defineProperty(t,"__esModule",{value:!0})}));
//# sourceMappingURL=index.js.map

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

import { DevbookStatus, Env, FS, Config } from '../core';
import { DevbookStatus, Env, FS, Terminal, Config } from '../core';
/**

@@ -50,3 +50,3 @@ * Options passed to the {@link useDevbook} hook.

*/
runCmd: (command: string) => void;
runCmd: (command: string) => Promise<void>;
/**

@@ -56,2 +56,8 @@ * Use this for accessing and manipulating this Devbook's VM's filesystem.

fs?: FS;
/**
* Use this for managing terminal sessions.
*
* This object is used internally by the `Terminal` component from Devbook UI package - https://github.com/devbookhq/ui#terminal.
*/
terminal?: Terminal;
}

@@ -58,0 +64,0 @@ /**

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

@@ -27,6 +27,6 @@ "homepage": "https://usedevbook.com",

"@rollup/plugin-node-resolve": "^13.1.3",
"@types/node": "^17.0.17",
"@types/react": "^17.0.39",
"@types/react-dom": "^17.0.11",
"rollup": "^2.67.2",
"@types/node": "^17.0.21",
"@types/react": "^17.0.40",
"@types/react-dom": "^17.0.13",
"rollup": "^2.70.1",
"rollup-plugin-auto-external": "^2.0.0",

@@ -36,3 +36,3 @@ "rollup-plugin-polyfill-node": "^0.8.0",

"rollup-plugin-typescript2": "^0.31.2",
"typescript": "^4.5.5"
"typescript": "^4.6.2"
},

@@ -56,2 +56,2 @@ "files": [

]
}
}

@@ -35,3 +35,3 @@ # Devbook SDK

// 3. Use the hook
const { stdout, stderr, status, url, fs, runCmd } = useDevbook({ env: 'nodejs-v16', port: 3000 })
const { stdout, stderr, status, fs, runCmd } = useDevbook({ env: 'your-node-env' })

@@ -52,8 +52,3 @@ async function handleRun() {

{status === DevbookStatus.Connecting && <div>Status: Starting VM...</div>}
{status === DevbookStatus.Connected &&
<>
<div>URL for the port 3000 on the VM: {url}</div>
<button onClick={handleRun}>Run</button>
</>
)}
{status === DevbookStatus.Connected && <button onClick={handleRun}>Run</button>}
<h3>Output</h3>

@@ -81,3 +76,3 @@ {stdout.map((o, idx) => <span key={`out_${idx}`}>{o}</span>)}

const dbk = new Devbook({
env: 'nodejs-v16',
env: 'your-node-env',
onStdout(out) {

@@ -92,6 +87,2 @@ console.log('stdout', { err })

},
onURLChange(getURL) {
const url = getURL(3000) // Create a URL that connects to the port 3000
console.log('url', { url })
},
})

@@ -111,7 +102,5 @@

## Supported runtimes
- NodeJS
- Looking for more runtimes? Please open an [issue](https://github.com/DevbookHQ/sdk/issues)
- *(coming soon)* Custom environments based on containers
We support any environments based on Docker images - check out our [CLI tool](https://github.com/devbookhq/devbookctl) for creating and deploying custom Devbook envs.
## Usage of Devbook in example apps
- [React](examples/react-app)

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