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 0.1.2 to 0.1.3

lib/cjs/core/runningEnvironment/webSocket.d.ts

3

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

@@ -25,3 +25,4 @@ export declare enum TRunner {

CmdExit = "RunningEnvironment.CmdExit",
RunningCmds = "RunningEnvironment.RunningCmds"
RunningCmds = "RunningEnvironment.RunningCmds",
RunCode = "RunningEnvironment.Run"
}

@@ -28,0 +29,0 @@ export declare enum TCodeCell {

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, } 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, } 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;
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;
payload: {

@@ -293,1 +293,18 @@ environmentID: string;

}
/**
* Sent to remote runner Runner to run a single command.
* Usually like so: `node index.js`.
*/
export interface RunningEnvironment_RunCode extends BaseRunningEnvironment {
type: TRunningEnvironment.RunCode;
payload: {
environmentID: string;
/**
* A unique ID that Runner received via the `RunningEnvironment_ExecCmd` message.
*/
executionID: string;
code: string;
filename: string;
command: string;
};
}
import { TemplateConfig } from 'src/common-ts/TemplateConfig';
/**
* Runtime environments that you can use with the Devbook VM.
* Runtime environments that you can use with the Devbooks' VMs.
*/

@@ -14,3 +14,4 @@ export declare enum Env {

toCommand: (code: string) => string;
fileExtension: string;
};
};

@@ -20,5 +20,5 @@ import { Env } from './constants';

/**
* Class representing connection to a VM that is used for running code and commands.
* Representation of a connection to a VM that is used for running code and commands.
*
* You can have multiple `Devbook` class instances -
* You can have multiple `Devbook` class instances connected to the same VM -
* instances with the same `env`({@link Env}) parameter passed to the constructor will share filesystem and process namespace.

@@ -48,7 +48,7 @@ */

/**
* Environment that this Devbook should use.
* Environment that this `Devbook` should use.
*
* This affects which runtime (NodeJS, etc...) will be available and used in the {@link Devbook.runCode} function.
*
* {@link Devbook} classes with different environments are isolated - each has their own filesystem and process namespace.
* `Devbook` instances with different environments are isolated - each has their own filesystem and process namespace.
*/

@@ -69,3 +69,3 @@ env: Env;

/**
* If this value is true then this Devbook will print detailed logs.
* If this value is true then this `Devbook` will print detailed logs.
*/

@@ -77,3 +77,3 @@ debug?: boolean;

*
* This {@link Devboook}'s VM shares filesystem and process namespace with other Devbook`s with the same `env`({@link Env}) passed to their constructors.
* This {@link Devboook}'s VM shares filesystem and process namespace with other `Devbook`'s with the same `env`({@link Env}) passed to their constructors.
*

@@ -86,3 +86,3 @@ * @param command Command to run

*
* This {@link Devboook}'s VM shares filesystem and process namespace with other Devbook`s with the same `env`({@link Env}) passed to their constructors.
* This {@link Devboook}'s VM shares filesystem and process namespace with other `Devbook`'s with the same `env`({@link Env}) passed to their constructors.
*

@@ -93,3 +93,3 @@ * @param code Code to run

/**
* Disconnect this Devbook from the VM.
* Disconnect this `Devbook` from the VM.
*/

@@ -96,0 +96,0 @@ destroy(): void;

@@ -18,9 +18,8 @@ import * as rws from 'src/common-ts/RunnerWebSocket';

private readonly opts;
private logger?;
get contextID(): string;
envs: RunningEnvironment[];
private unsubscribeConnHandler;
private readonly logger;
private get contextID();
private fsWriteSubscribers;
private envs;
private readonly unsubscribeConnHandler;
constructor(opts: EvaluationContextOpts);
handleConnectionOpen(): void;
handleConnectionClose(): void;
/**

@@ -32,17 +31,25 @@ * Restarts all context's objects to their default state.

destroy(): void;
private handleConnectionMessage;
deleteRunningEnvironment({ templateID }: {
templateID: string;
}): void;
createRunningEnvironment({ templateID }: {
executeCode({ templateID, executionID, code }: {
templateID: Env;
}): RunningEnvironment;
vmenv_handleStartAck(payload: rws.RunningEnvironment_StartAck['payload']): void;
vmenv_handleCmdOut(payload: rws.RunningEnvironment_CmdOut['payload']): void;
executionID: string;
code: string;
}): Promise<void>;
executeCommand({ templateID, executionID, command }: {
templateID: string;
templateID: Env;
executionID: string;
command: string;
}): void;
createRunningEnvironment({ templateID }: {
templateID: Env;
}): void;
private subscribeFSWrite;
private unsubscribeFSWrite;
private handleConnectionOpen;
private handleConnectionClose;
private handleConnectionMessage;
private vmenv_handleCmdExit;
private vmenv_handleFSEventWrite;
private vmenv_handleStartAck;
private vmenv_handleCmdOut;
}
export default EvaluationContext;

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

export { default as Devbook, DevbookStatus } from './devbook';
export { default as Devbook, DevbookStatus, } from './devbook';
export { Env } from './constants';
import RunningEnvironment from './runningEnvironment';
import * as ws from './ws';
import * as ws from './webSocket';
export { RunningEnvironment, ws, };
export { useDevbook } from './react';
export { Devbook, Env, DevbookStatus } from './core';
export { Devbook, Env, DevbookStatus, } from './core';

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

"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react");exports.Env=void 0,(exports.Env||(exports.Env={})).NodeJS="nodejs-v16";const t={"nodejs-v16":{id:"nodejs-v16",image:"us-central1-docker.pkg.dev/devbookhq/devbook-runner-templates/nodejs-v16:latest",root_dir:"/home/runner",code_cells_dir:"/home/runner/src",toCommand:e=>`node -e "${e}"`}};class n{constructor(e,t=!1){this.logID=e,this.isEnabled=t}id(){return"function"==typeof this.logID?this.logID():this.logID}log(...e){this.isEnabled&&console.log(`[${this.id()}]`,...e)}warn(...e){this.isEnabled&&console.warn(`[${this.id()}]`,...e)}error(...e){console.error(`[${this.id()} ERROR]`,...e)}}
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e,t,n,s=require("react");class i{constructor(e,t=!1){this.logID=e,this.isEnabled=t}id(){return"function"==typeof this.logID?this.logID():this.logID}log(...e){this.isEnabled&&console.log(`[${this.id()}]`,...e)}warn(...e){this.isEnabled&&console.warn(`[${this.id()}]`,...e)}error(...e){console.error(`[${this.id()} ERROR]`,...e)}}
/*! *****************************************************************************

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

PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */function s(e,t,n,s){return new(n||(n=Promise))((function(i,o){function r(e){try{l(s.next(e))}catch(e){o(e)}}function a(e){try{l(s.throw(e))}catch(e){o(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(r,a)}l((s=s.apply(e,t||[])).next())}))}function i(e){return new Promise((t=>setTimeout(t,e)))}var o,r,a;!function(e){e.Error="Runner.Error"}(o||(o={})),function(e){e.Start="RunningEnvironment.Start",e.StartAck="RunningEnvironment.StartAck",e.Eval="RunningEnvironment.Eval",e.FSEventCreate="RunningEnvironment.FSEventCreate",e.FSEventRemove="RunningEnvironment.FSEventRemove",e.FSEventWrite="RunningEnvironment.FSEventWrite",e.CreateDir="RunningEnvironment.CreateDir",e.ListDir="RunningEnvironment.ListDir",e.WriteFile="RunningEnvironment.WriteFile",e.GetFile="RunningEnvironment.GetFile",e.RemoveFile="RunningEnvironment.RemoveFile",e.DirContent="RunningEnvironment.DirContent",e.FileContent="RunningEnvironment.FileContent",e.Stdout="RunningEnvironment.Stdout",e.Stderr="RunningEnvironment.Stderr",e.ExecCmd="RunningEnvironment.ExecCmd",e.KillCmd="RunningEnvironment.KillCmd",e.ListRunningCmds="RunningEnvironment.ListRunningCmds",e.CmdOut="RunningEnvironment.CmdOut",e.CmdExit="RunningEnvironment.CmdExit",e.RunningCmds="RunningEnvironment.RunningCmds"}(r||(r={})),function(e){e.Error="CodeCell.Error"}(a||(a={}));const l={Runner:o,RunningEnvironment:r,CodeCell:a};class c{constructor(){this.url="wss://orchestrator.usedevbook.com",this.logger=new n("WebSocketConnection"),this.handlers=[]}get state(){var e;return null===(e=this.client)||void 0===e?void 0:e.readyState}get isClosed(){if(void 0!==this.client)return this.client.readyState===this.client.CLOSED}get isClosing(){if(void 0!==this.client)return this.client.readyState===this.client.CLOSING}get isOpen(){if(void 0!==this.client)return this.client.readyState===this.client.OPEN}get isConnecting(){if(void 0!==this.client)return this.client.readyState===this.client.CONNECTING}subscribeHandler(e){return this.handlers.push(e),()=>{this.handlers=this.handlers.filter((t=>t!==e))}}connect(e){(!this.client||this.client.readyState!==this.client.CONNECTING&&this.client.readyState!==this.client.OPEN)&&(e||this.sessionID?(e?(this.logger.log(`Will try to connect to session "${e}"`),this.sessionID=e):!e&&this.sessionID&&this.logger.log(`Will try to connect to previous session "${this.sessionID}"`),this.client=new WebSocket(`${this.url}/session/ws/${this.sessionID}`),this.client.onopen=()=>this.handleOpen(),this.client.onmessage=e=>{this.logger.log("Received (raw)",{msg:e}),this.handleMessage(e)},this.client.onerror=e=>this.handleError(e),this.client.onclose=e=>this.handleClose(e)):this.logger.error("Cannot connect, no session ID passed to the function and no session ID saved from the previous session"))}send(e){this.client&&this.client.readyState===this.client.OPEN?(this.logger.log("Send",e),this._send(e)):this.logger.warn("Trying to send a message while not being in the `OPEN` state or without established connection, message will be discarded",e)}close(){var e;this.logger.log("Closing connection"),null===(e=this.client)||void 0===e||e.close(1e3)}handleOpen(){var e;this.logger.log("Connection opened",{readyState:null===(e=this.client)||void 0===e?void 0:e.readyState}),this.handlers.forEach((e=>e.onOpen()))}_send(e){var t,n;null===(t=this.client)||void 0===t||t.send((n=e,JSON.stringify(n,(()=>{const e=new WeakSet;return(t,n)=>{if("object"==typeof n&&null!==n){if(e.has(n))return;e.add(n)}return n}})(),2)))}handleClose(e){return s(this,void 0,void 0,(function*(){this.logger.log("Connection closed",e),this.handlers.forEach((e=>e.onClose())),this.logger.log("Will try to reconnect in 3s"),yield i(3e3),this.connect()}))}handleError(e){var t;this.logger.error("Connection error",e),null===(t=this.client)||void 0===t||t.close()}handleMessage(e){if(!e.data)return void this.logger.error("Message has empty data field",e);const t=JSON.parse(e.data);if(!t.type)return void this.logger.error("Message has no type",t);const n=t;Object.values(l.RunningEnvironment).includes(n.type)||Object.values(l.Runner).includes(n.type)||Object.values(l.CodeCell).includes(n.type)?n.type!==l.Runner.Error?(this.logger.log("Received (parsed)",n),this.handlers.forEach((e=>e.onMessage(n)))):this.logger.error("Runner error",n):this.logger.error('Message "type" field has unexpected value',n)}}var d,h;!function(e){e.Ok="Ok",e.Terminated="Terminated"}(d||(d={}));class u{constructor(e,t=new Date){this.id=e,this.lastPing=t,this.logger=new n("RunnerSession"),this.url="https://orchestrator.usedevbook.com"}ping(){return s(this,void 0,void 0,(function*(){this.logger.log(`Pinging session "${this.id}"`);const e=JSON.stringify({sessionID:this.id});try{const t=yield fetch(`${this.url}/session/ping`,{method:"POST",headers:{"Content-Type":"application/json"},body:e}),n=yield t.json();if(!t.ok)throw this.logger.error(t.headers,n),new Error("Non-OK response when trying to ping active Runner session");if(n.status===d.Terminated)throw new Error(`[keepAlive]: Session '${this.id}' is terminated`);this.lastPing=new Date}catch(e){throw this.logger.error(e),new Error("Failed to ping active Runner session")}}))}}!function(e){e.Connected="Connected",e.Connecting="Connecting",e.Disconnected="Disconnected"}(h||(h={}));class g{constructor(e){this.conn=e,this.logger=new n("SessionManager"),this.url="https://orchestrator.usedevbook.com",this.isGettingSessionActive=!1,this.status=h.Disconnected,this.logger.log("Initialize"),this.getSession()}get cachedSessionID(){return sessionStorage.getItem("dbk_sdk_session_id")}set cachedSessionID(e){null===e?(this.logger.log("Cleared last sessionID"),sessionStorage.removeItem("dbk_sdk_session_id")):(this.logger.log(`Saved sessionID "${e}" as last sessionID`),sessionStorage.setItem("dbk_sdk_session_id",e))}reset(){this.logger.log("Reset"),this.status=h.Disconnected,this.cachedSessionID=null,this.conn.close(),this.session=void 0}getSession(){var e;return s(this,void 0,void 0,(function*(){if(!this.isGettingSessionActive)for(this.isGettingSessionActive=!0;;){this.status=h.Connecting;try{const t=this.cachedSessionID?`${this.url}/session/${this.cachedSessionID}`:`${this.url}/session`;this.cachedSessionID?this.logger.log(`Restoring old Runner session "${this.cachedSessionID}"`):this.logger.log("Acquiring new Runner session");const n=yield fetch(t),s=yield n.json();if(!n.ok){this.logger.error("Non-OK response when trying to ping active Runner session. Will try again in 3s",n.headers,s),yield i(3e3);continue}for(this.session=new u(s.sessionID),this.logger.log(`Acquired session "${this.session.id}"`),this.cachedSessionID=this.session.id,this.status=h.Connected,this.conn.connect(this.session.id),this.logger.log(`Started pinging session "${this.session.id}"`);this.session;)try{yield this.session.ping(),yield i(5e3)}catch(e){this.logger.error(`Failed to ping session "${this.session.id}"`,e);break}this.logger.log(`Stopped pinging session "${null===(e=this.session)||void 0===e?void 0:e.id}"`),this.session=void 0,this.status=h.Disconnected,this.conn.close()}catch(e){this.logger.error("Failed to acquire Runner session. Will try again in 3s",e),yield i(3e3)}}}))}}function v(e){return function(e){const t=Array.from(e).reduce(((e,t)=>0|31*e+t.charCodeAt(0)),0);return("0000000"+(t>>>0).toString(16)).slice(-8)}(e)}class m{constructor(e,n){this.contextID=e,this.templateID=n,this.isReady=!1,this.id=`${e}_${v(n)}`,this.template=t[this.templateID]}}function p(e,{environmentID:t,template:n}){const s={type:l.RunningEnvironment.Start,payload:{environmentID:t,template:n}};e.send(s)}class D{constructor(e){this.opts=e,this.envs=[],this.logger=new n("EvaluationContext",e.debug),this.unsubscribeConnHandler=this.opts.conn.subscribeHandler({onOpen:this.handleConnectionOpen.bind(this),onMessage:this.handleConnectionMessage.bind(this),onClose:this.handleConnectionClose.bind(this)}),this.opts.conn.isOpen&&this.handleConnectionOpen(),this.opts.conn.isClosed&&this.handleConnectionClose()}get contextID(){return this.opts.contextID}handleConnectionOpen(){var e,t;this.restart(),null===(t=(e=this.opts).onSessionChange)||void 0===t||t.call(e,{status:h.Connected})}handleConnectionClose(){var e,t;null===(t=(e=this.opts).onSessionChange)||void 0===t||t.call(e,{status:h.Connecting})}restart(){var e;return null===(e=this.logger)||void 0===e||e.log("Restart - session:",this.opts.conn.sessionID),this.envs.forEach((e=>{e.isReady=!1,p(this.opts.conn,{environmentID:e.id,template:e.template})}))}destroy(){var e;null===(e=this.logger)||void 0===e||e.log("Destroy"),this.envs=[],this.unsubscribeConnHandler()}handleConnectionMessage(e){var t,n;switch(null===(t=this.logger)||void 0===t||t.log("Handling message from remote Runner",{message:e}),e.type){case l.RunningEnvironment.StartAck:{const t=e;this.vmenv_handleStartAck(t.payload);break}case l.RunningEnvironment.CmdOut:{const t=e;this.vmenv_handleCmdOut(t.payload);break}default:null===(n=this.logger)||void 0===n||n.warn("Unknown message type",{message:e})}}deleteRunningEnvironment({templateID:e}){var t;null===(t=this.logger)||void 0===t||t.log('Handling "DeleteEnvironment"',{templateID:e}),this.envs=this.envs.filter((t=>t.templateID!==e))}createRunningEnvironment({templateID:e}){var t,n,s;null===(t=this.logger)||void 0===t||t.log('Handling "CreateEnvironment"',{templateID:e});const i=this.envs.find((t=>t.templateID===e));if(i)return i;const o=new m(this.contextID,e);return this.envs=[...this.envs,o],p(this.opts.conn,{environmentID:o.id,template:o.template}),null===(s=(n=this.opts).onEnvChange)||void 0===s||s.call(n,o),o}vmenv_handleStartAck(e){var t,n,s,i;null===(t=this.logger)||void 0===t||t.log('[vmenv] Handling "StartAck"',{payload:e});const o=this.envs.find((t=>t.id===e.environmentID));o?(o.isReady=!0,null===(i=(s=this.opts).onEnvChange)||void 0===i||i.call(s,o)):null===(n=this.logger)||void 0===n||n.warn("Environment not found",{payload:e})}vmenv_handleCmdOut(e){var t,n,s;null===(t=this.logger)||void 0===t||t.log('[vmenv] Handling "CmdOut"',e),null===(s=(n=this.opts).onCmdOut)||void 0===s||s.call(n,e)}executeCommand({templateID:e,executionID:t,command:n}){var s,i,o;null===(s=this.logger)||void 0===s||s.log("Exec shell code cell",{templateID:e,executionID:t,command:n});const r=this.envs.find((t=>t.templateID===e));r?r.isReady?function(e,{environmentID:t,executionID:n,command:s}){const i={type:l.RunningEnvironment.ExecCmd,payload:{environmentID:t,executionID:n,command:s}};e.send(i)}(this.opts.conn,{environmentID:r.id,executionID:t,command:n}):null===(o=this.logger)||void 0===o||o.error("Environment is not ready",{templateID:e,executionID:t,command:n}):null===(i=this.logger)||void 0===i||i.error("Environment not found",{templateID:e,executionID:t,command:n})}}class C{constructor(){this.logger=new n("Runner"),this.conn=new c,this.sessManager=new g(this.conn)}static get obj(){return C._obj||(C._obj=new C)}get session(){return this.sessManager.session}get status(){return this.sessManager.status}reset(){this.logger.log("Reset"),this.sessManager.reset()}createContext(e){return new D(Object.assign(Object.assign({},e),{conn:this.conn}))}__debug__loadNewSession(){this.logger.log("__debug__loadNewSession"),this.sessManager.reset()}}const S=(E="1234567890abcdefghijklmnopqrstuvwxyz",y=6,()=>{let e="",t=y;for(;t--;)e+=E[Math.random()*E.length|0];return e});var E,y,R;exports.DevbookStatus=void 0,(R=exports.DevbookStatus||(exports.DevbookStatus={}))[R.Disconnected=0]="Disconnected",R[R.Connecting=1]="Connecting",R[R.Connected=2]="Connected";class I{constructor(e){this.opts=e,this._isDestroyed=!1,this._isEnvReady=!1,this._sessionStatus=h.Disconnected,this._status=exports.DevbookStatus.Disconnected;const t="default";this.contextID=t;const n=S();this.executionID=n;const s=e=>this.isEnvReady=e,i=e=>this.sessionStatus=e;this.context=C.obj.createContext({debug:e.debug,contextID:t,onEnvChange(e){s(e.isReady)},onSessionChange({status:e}){i(e)},onCmdOut(t){var s,i;t.executionID===n&&(void 0!==t.stdout&&(null===(s=e.onStdout)||void 0===s||s.call(e,t.stdout)),void 0!==t.stderr&&(null===(i=e.onStderr)||void 0===i||i.call(e,t.stderr)))}}),this.context.createRunningEnvironment({templateID:e.env})}get isDestroyed(){return this._isDestroyed}set isDestroyed(e){this._isDestroyed=e,this.updateStatus()}get isEnvReady(){return this._isEnvReady}set isEnvReady(e){this._isEnvReady=e,this.updateStatus()}get sessionStatus(){return this._sessionStatus}set sessionStatus(e){this._sessionStatus=e,this.updateStatus()}get status(){return this._status}set status(e){var t,n;this._status=e,null===(n=(t=this.opts).onStatusChange)||void 0===n||n.call(t,e)}runCmd(e){this.status!==exports.DevbookStatus.Disconnected&&this.context.executeCommand({templateID:this.opts.env,executionID:this.executionID,command:e})}runCode(e){const n=t[this.opts.env].toCommand(e);this.runCmd(n)}destroy(){this.context.destroy(),this.isDestroyed=!0}updateStatus(){if(this.isDestroyed)return void(this.status!==exports.DevbookStatus.Disconnected&&(this.status=exports.DevbookStatus.Disconnected));let e;switch(this.sessionStatus){case h.Disconnected:e=exports.DevbookStatus.Disconnected;break;case h.Connecting:e=exports.DevbookStatus.Connecting;break;case h.Connected:if(!this.isEnvReady){e=exports.DevbookStatus.Connecting;break}e=exports.DevbookStatus.Connected}this.status=e}}exports.Devbook=I,exports.useDevbook=function({env:t,debug:n}){const[s,i]=e.useState(),[o,r]=e.useState(exports.DevbookStatus.Disconnected),[a,l]=e.useState([]),[c,d]=e.useState([]),h=e.useCallback((e=>{s&&(d([]),l([]),s.runCmd(e))}),[s]),u=e.useCallback((e=>{s&&(d([]),l([]),s.runCode(e))}),[s]);return e.useEffect((function(){const e=new I({debug:n,env:t,onStatusChange(e){r(e)},onStderr(e){l((t=>[...t,e]))},onStdout(e){d((t=>[...t,e]))}});return d([]),l([]),i(e),()=>{e.destroy()}}),[t,n]),{stderr:a,stdout:c,runCmd:h,runCode:u,status:o}};
***************************************************************************** */function o(e,t,n,s){return new(n||(n=Promise))((function(i,o){function r(e){try{c(s.next(e))}catch(e){o(e)}}function a(e){try{c(s.throw(e))}catch(e){o(e)}}function c(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(r,a)}c((s=s.apply(e,t||[])).next())}))}function r(e){return new Promise((t=>setTimeout(t,e)))}!function(e){e.Error="Runner.Error"}(e||(e={})),function(e){e.Start="RunningEnvironment.Start",e.StartAck="RunningEnvironment.StartAck",e.Eval="RunningEnvironment.Eval",e.FSEventCreate="RunningEnvironment.FSEventCreate",e.FSEventRemove="RunningEnvironment.FSEventRemove",e.FSEventWrite="RunningEnvironment.FSEventWrite",e.CreateDir="RunningEnvironment.CreateDir",e.ListDir="RunningEnvironment.ListDir",e.WriteFile="RunningEnvironment.WriteFile",e.GetFile="RunningEnvironment.GetFile",e.RemoveFile="RunningEnvironment.RemoveFile",e.DirContent="RunningEnvironment.DirContent",e.FileContent="RunningEnvironment.FileContent",e.Stdout="RunningEnvironment.Stdout",e.Stderr="RunningEnvironment.Stderr",e.ExecCmd="RunningEnvironment.ExecCmd",e.KillCmd="RunningEnvironment.KillCmd",e.ListRunningCmds="RunningEnvironment.ListRunningCmds",e.CmdOut="RunningEnvironment.CmdOut",e.CmdExit="RunningEnvironment.CmdExit",e.RunningCmds="RunningEnvironment.RunningCmds",e.RunCode="RunningEnvironment.Run"}(t||(t={})),function(e){e.Error="CodeCell.Error"}(n||(n={}));const a={Runner:e,RunningEnvironment:t,CodeCell:n};exports.Env=void 0,(exports.Env||(exports.Env={})).NodeJS="nodejs-v16";const c={"nodejs-v16":{id:"nodejs-v16",fileExtension:".js",image:"us-central1-docker.pkg.dev/devbookhq/devbook-runner-templates/nodejs-v16:latest",root_dir:"/home/runner",code_cells_dir:"/home/runner/src",toCommand:e=>`node "${e}"`}};class l{constructor(){this.url="wss://orchestrator.usedevbook.com",this.logger=new i("WebSocketConnection"),this.handlers=[]}get state(){var e;return null===(e=this.client)||void 0===e?void 0:e.readyState}get isClosed(){if(void 0!==this.client)return this.client.readyState===this.client.CLOSED}get isClosing(){if(void 0!==this.client)return this.client.readyState===this.client.CLOSING}get isOpen(){if(void 0!==this.client)return this.client.readyState===this.client.OPEN}get isConnecting(){if(void 0!==this.client)return this.client.readyState===this.client.CONNECTING}subscribeHandler(e){return this.handlers.push(e),()=>{this.handlers=this.handlers.filter((t=>t!==e))}}connect(e){(!this.client||this.client.readyState!==this.client.CONNECTING&&this.client.readyState!==this.client.OPEN)&&(e||this.sessionID?(e?(this.logger.log(`Will try to connect to session "${e}"`),this.sessionID=e):!e&&this.sessionID&&this.logger.log(`Will try to connect to previous session "${this.sessionID}"`),this.client=new WebSocket(`${this.url}/session/ws/${this.sessionID}`),this.client.onopen=()=>this.handleOpen(),this.client.onmessage=e=>{this.logger.log("Received (raw)",{msg:e}),this.handleMessage(e)},this.client.onerror=e=>this.handleError(e),this.client.onclose=e=>this.handleClose(e)):this.logger.error("Cannot connect, no session ID passed to the function and no session ID saved from the previous session"))}send(e){this.client&&this.client.readyState===this.client.OPEN?(this.logger.log("Send",e),this._send(e)):this.logger.warn("Trying to send a message while not being in the `OPEN` state or without established connection, message will be discarded",e)}close(){var e;this.logger.log("Closing connection"),null===(e=this.client)||void 0===e||e.close(1e3)}handleOpen(){var e;this.logger.log("Connection opened",{readyState:null===(e=this.client)||void 0===e?void 0:e.readyState}),this.handlers.forEach((e=>e.onOpen()))}_send(e){var t,n;null===(t=this.client)||void 0===t||t.send((n=e,JSON.stringify(n,(()=>{const e=new WeakSet;return(t,n)=>{if("object"==typeof n&&null!==n){if(e.has(n))return;e.add(n)}return n}})(),2)))}handleClose(e){return o(this,void 0,void 0,(function*(){this.logger.log("Connection closed",e),this.handlers.forEach((e=>e.onClose())),this.logger.log("Will try to reconnect in 3s"),yield r(3e3),this.connect()}))}handleError(e){var t;this.logger.error("Connection error",e),null===(t=this.client)||void 0===t||t.close()}handleMessage(e){if(!e.data)return void this.logger.error("Message has empty data field",e);const t=JSON.parse(e.data);if(!t.type)return void this.logger.error("Message has no type",t);const n=t;Object.values(a.RunningEnvironment).includes(n.type)||Object.values(a.Runner).includes(n.type)||Object.values(a.CodeCell).includes(n.type)?n.type!==a.Runner.Error?(this.logger.log("Received (parsed)",n),this.handlers.forEach((e=>e.onMessage(n)))):this.logger.error("Runner error",n):this.logger.error('Message "type" field has unexpected value',n)}}var h,d;!function(e){e.Ok="Ok",e.Terminated="Terminated"}(h||(h={}));class u{constructor(e,t=new Date){this.id=e,this.lastPing=t,this.logger=new i("RunnerSession"),this.url="https://orchestrator.usedevbook.com"}ping(){return o(this,void 0,void 0,(function*(){this.logger.log(`Pinging session "${this.id}"`);const e=JSON.stringify({sessionID:this.id});try{const t=yield fetch(`${this.url}/session/ping`,{method:"POST",headers:{"Content-Type":"application/json"},body:e}),n=yield t.json();if(!t.ok)throw this.logger.error(t.headers,n),new Error("Non-OK response when trying to ping active Runner session");if(n.status===h.Terminated)throw new Error(`[keepAlive]: Session '${this.id}' is terminated`);this.lastPing=new Date}catch(e){throw this.logger.error(e),new Error("Failed to ping active Runner session")}}))}}!function(e){e.Connected="Connected",e.Connecting="Connecting",e.Disconnected="Disconnected"}(d||(d={}));class g{constructor(e){this.conn=e,this.logger=new i("SessionManager"),this.url="https://orchestrator.usedevbook.com",this.isGettingSessionActive=!1,this.status=d.Disconnected,this.logger.log("Initialize"),this.getSession()}get cachedSessionID(){return sessionStorage.getItem("dbk_sdk_session_id")}set cachedSessionID(e){null===e?(this.logger.log("Cleared last sessionID"),sessionStorage.removeItem("dbk_sdk_session_id")):(this.logger.log(`Saved sessionID "${e}" as last sessionID`),sessionStorage.setItem("dbk_sdk_session_id",e))}reset(){this.logger.log("Reset"),this.status=d.Disconnected,this.cachedSessionID=null,this.conn.close(),this.session=void 0}getSession(){var e;return o(this,void 0,void 0,(function*(){if(!this.isGettingSessionActive)for(this.isGettingSessionActive=!0;;){this.status=d.Connecting;try{const t=this.cachedSessionID?`${this.url}/session/${this.cachedSessionID}`:`${this.url}/session`;this.cachedSessionID?this.logger.log(`Restoring old Runner session "${this.cachedSessionID}"`):this.logger.log("Acquiring new Runner session");const n=yield fetch(t),s=yield n.json();if(!n.ok){this.logger.error("Non-OK response when trying to ping active Runner session. Will try again in 3s",n.headers,s),yield r(3e3);continue}for(this.session=new u(s.sessionID),this.logger.log(`Acquired session "${this.session.id}"`),this.cachedSessionID=this.session.id,this.status=d.Connected,this.conn.connect(this.session.id),this.logger.log(`Started pinging session "${this.session.id}"`);this.session;)try{yield this.session.ping(),yield r(5e3)}catch(e){this.logger.error(`Failed to ping session "${this.session.id}"`,e);break}this.logger.log(`Stopped pinging session "${null===(e=this.session)||void 0===e?void 0:e.id}"`),this.session=void 0,this.status=d.Disconnected,this.conn.close()}catch(e){this.logger.error("Failed to acquire Runner session. Will try again in 3s",e),yield r(3e3)}}}))}}function v(e,t){for(var n=0,s=e.length-1;s>=0;s--){var i=e[s];"."===i?e.splice(s,1):".."===i?(e.splice(s,1),n++):n&&(e.splice(s,1),n--)}if(t)for(;n--;n)e.unshift("..");return e}var m=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/,p=function(e){return m.exec(e).slice(1)};function D(){for(var e="",t=!1,n=arguments.length-1;n>=-1&&!t;n--){var s=n>=0?arguments[n]:"/";if("string"!=typeof s)throw new TypeError("Arguments to path.resolve must be strings");s&&(e=s+"/"+e,t="/"===s.charAt(0))}return(t?"/":"")+(e=v(b(e.split("/"),(function(e){return!!e})),!t).join("/"))||"."}function f(e){var t=C(e),n="/"===y(e,-1);return(e=v(b(e.split("/"),(function(e){return!!e})),!t).join("/"))||t||(e="."),e&&n&&(e+="/"),(t?"/":"")+e}function C(e){return"/"===e.charAt(0)}var S={extname:function(e){return p(e)[3]},basename:function(e,t){var n=p(e)[2];return t&&n.substr(-1*t.length)===t&&(n=n.substr(0,n.length-t.length)),n},dirname:function(e){var t=p(e),n=t[0],s=t[1];return n||s?(s&&(s=s.substr(0,s.length-1)),n+s):"."},sep:"/",delimiter:":",relative:function(e,t){function n(e){for(var t=0;t<e.length&&""===e[t];t++);for(var n=e.length-1;n>=0&&""===e[n];n--);return t>n?[]:e.slice(t,n-t+1)}e=D(e).substr(1),t=D(t).substr(1);for(var s=n(e.split("/")),i=n(t.split("/")),o=Math.min(s.length,i.length),r=o,a=0;a<o;a++)if(s[a]!==i[a]){r=a;break}var c=[];for(a=r;a<s.length;a++)c.push("..");return(c=c.concat(i.slice(r))).join("/")},join:function(){var e=Array.prototype.slice.call(arguments,0);return f(b(e,(function(e,t){if("string"!=typeof e)throw new TypeError("Arguments to path.join must be strings");return e})).join("/"))},isAbsolute:C,normalize:f,resolve:D};function b(e,t){if(e.filter)return e.filter(t);for(var n=[],s=0;s<e.length;s++)t(e[s],s,e)&&n.push(e[s]);return n}var E,y="b"==="ab".substr(-1)?function(e,t,n){return e.substr(t,n)}:function(e,t,n){return t<0&&(t=e.length+t),e.substr(t,n)};function I(e){return function(e){const t=Array.from(e).reduce(((e,t)=>0|31*e+t.charCodeAt(0)),0);return("0000000"+(t>>>0).toString(16)).slice(-8)}(e)}class R{constructor(e,t){this.contextID=e,this.templateID=t,this.isReady=!1,this.id=`${e}_${I(t)}`,this.template=c[this.templateID]}}function x(e,{environmentID:t,template:n}){const s={type:a.RunningEnvironment.Start,payload:{environmentID:t,template:n}};e.send(s)}function k(e,{environmentID:t,executionID:n,command:s}){const i={type:a.RunningEnvironment.ExecCmd,payload:{environmentID:t,executionID:n,command:s}};e.send(i)}class w{constructor(e){this.opts=e,this.fsWriteSubscribers=[],this.envs=[],this.logger=new i("EvaluationContext",e.debug),this.unsubscribeConnHandler=this.opts.conn.subscribeHandler({onOpen:this.handleConnectionOpen.bind(this),onMessage:this.handleConnectionMessage.bind(this),onClose:this.handleConnectionClose.bind(this)}),this.opts.conn.isOpen&&this.handleConnectionOpen(),this.opts.conn.isClosed&&this.handleConnectionClose()}get contextID(){return this.opts.contextID}restart(){return this.logger.log("Restart",this.opts.conn.sessionID),this.envs.forEach((e=>{e.isReady=!1,x(this.opts.conn,{environmentID:e.id,template:e.template})}))}destroy(){this.logger.log("Destroy"),this.unsubscribeConnHandler(),this.envs=[],this.fsWriteSubscribers=[]}executeCode({templateID:e,executionID:t,code:n}){return o(this,void 0,void 0,(function*(){this.logger.log("Execute code",{templateID:e,executionID:t});const s=this.envs.find((t=>t.templateID===e));if(!s)return void this.logger.error("Environment not found",{templateID:e,executionID:t});if(!s.isReady)return void this.logger.error("Environment is not ready",{templateID:e,executionID:t});const i=c[e].fileExtension,o=`${t}${i}`,r=S.join("/src",o);let l;const h=new Promise(((e,t)=>{l=e,setTimeout((()=>{t()}),1e4)})),d=e=>{e.path.endsWith(r)&&l()};this.subscribeFSWrite(d),function(e,{environmentID:t,path:n,content:s}){const i={type:a.RunningEnvironment.WriteFile,payload:{environmentID:t,path:n,content:s}};e.send(i)}(this.opts.conn,{environmentID:s.id,path:r,content:n});try{yield h}catch(e){return void this.logger.error(`File ${r} not written to VM`)}finally{this.unsubscribeFSWrite(d)}const u=S.join(c[e].root_dir,r),g=c[e].toCommand(u);k(this.opts.conn,{environmentID:s.id,executionID:t,command:g})}))}executeCommand({templateID:e,executionID:t,command:n}){this.logger.log("Execute shell command",{templateID:e,executionID:t,command:n});const s=this.envs.find((t=>t.templateID===e));s?s.isReady?k(this.opts.conn,{environmentID:s.id,executionID:t,command:n}):this.logger.error("Environment is not ready",{templateID:e,executionID:t,command:n}):this.logger.error("Environment not found",{templateID:e,executionID:t,command:n})}createRunningEnvironment({templateID:e}){var t,n;this.logger.log("Creating running environment",{templateID:e});if(this.envs.find((t=>t.templateID===e)))return;const s=new R(this.contextID,e);this.envs=[...this.envs,s],x(this.opts.conn,{environmentID:s.id,template:s.template}),null===(n=(t=this.opts).onEnvChange)||void 0===n||n.call(t,s)}subscribeFSWrite(e){this.fsWriteSubscribers.push(e)}unsubscribeFSWrite(e){this.fsWriteSubscribers=this.fsWriteSubscribers.filter((t=>t!==e))}handleConnectionOpen(){var e,t;this.restart(),null===(t=(e=this.opts).onSessionChange)||void 0===t||t.call(e,{status:d.Connected})}handleConnectionClose(){var e,t;null===(t=(e=this.opts).onSessionChange)||void 0===t||t.call(e,{status:d.Connecting})}handleConnectionMessage(e){switch(this.logger.log("Handling message from remote Runner",{message:e}),e.type){case a.RunningEnvironment.StartAck:{const t=e;this.vmenv_handleStartAck(t.payload);break}case a.RunningEnvironment.CmdOut:{const t=e;this.vmenv_handleCmdOut(t.payload);break}case a.RunningEnvironment.CmdExit:{const t=e;this.vmenv_handleCmdExit(t.payload);break}case a.RunningEnvironment.FSEventWrite:{const t=e;this.vmenv_handleFSEventWrite(t.payload);break}default:this.logger.warn("Unknown message type",{message:e})}}vmenv_handleCmdExit(e){var t,n;void 0!==e.error&&(null===(n=(t=this.opts).onCmdOut)||void 0===n||n.call(t,{environmentID:e.environmentID,executionID:e.executionID,stderr:e.error}))}vmenv_handleFSEventWrite(e){this.logger.log('[vmenv] Handling "FSEventWrite"',e);this.envs.find((t=>t.id===e.environmentID))?this.fsWriteSubscribers.forEach((t=>t(e))):this.logger.warn("Environment not found",{payload:e})}vmenv_handleStartAck(e){var t,n;this.logger.log('[vmenv] Handling "StartAck"',{payload:e});const s=this.envs.find((t=>t.id===e.environmentID));s?(s.isReady=!0,null===(n=(t=this.opts).onEnvChange)||void 0===n||n.call(t,s)):this.logger.warn("Environment not found",{payload:e})}vmenv_handleCmdOut(e){var t,n;this.logger.log('[vmenv] Handling "CmdOut"',e),null===(n=(t=this.opts).onCmdOut)||void 0===n||n.call(t,e)}}class _{constructor(){this.logger=new i("Runner"),this.conn=new l,this.sessManager=new g(this.conn)}static get obj(){return _._obj||(_._obj=new _)}get session(){return this.sessManager.session}get status(){return this.sessManager.status}reset(){this.logger.log("Reset"),this.sessManager.reset()}createContext(e){return new w(Object.assign(Object.assign({},e),{conn:this.conn}))}__debug__loadNewSession(){this.logger.log("__debug__loadNewSession"),this.sessManager.reset()}}exports.DevbookStatus=void 0,(E=exports.DevbookStatus||(exports.DevbookStatus={}))[E.Disconnected=0]="Disconnected",E[E.Connecting=1]="Connecting",E[E.Connected=2]="Connected";class O{constructor(e){this.opts=e,this._isDestroyed=!1,this._isEnvReady=!1,this._sessionStatus=d.Disconnected,this._status=exports.DevbookStatus.Disconnected;const t="default";this.contextID=t;this.executionID="def";const n=e=>this.isEnvReady=e,s=e=>this.sessionStatus=e;this.context=_.obj.createContext({debug:e.debug,contextID:t,onEnvChange(e){n(e.isReady)},onSessionChange({status:e}){s(e)},onCmdOut(t){var n,s;"def"===t.executionID&&(void 0!==t.stdout&&(null===(n=e.onStdout)||void 0===n||n.call(e,t.stdout)),void 0!==t.stderr&&(null===(s=e.onStderr)||void 0===s||s.call(e,t.stderr)))}}),this.context.createRunningEnvironment({templateID:e.env})}get isDestroyed(){return this._isDestroyed}set isDestroyed(e){this._isDestroyed=e,this.updateStatus()}get isEnvReady(){return this._isEnvReady}set isEnvReady(e){this._isEnvReady=e,this.updateStatus()}get sessionStatus(){return this._sessionStatus}set sessionStatus(e){this._sessionStatus=e,this.updateStatus()}get status(){return this._status}set status(e){var t,n;this._status=e,null===(n=(t=this.opts).onStatusChange)||void 0===n||n.call(t,e)}runCmd(e){this.status!==exports.DevbookStatus.Disconnected&&this.context.executeCommand({templateID:this.opts.env,executionID:this.executionID,command:e})}runCode(e){this.status!==exports.DevbookStatus.Disconnected&&this.context.executeCode({templateID:this.opts.env,executionID:this.executionID,code:e})}destroy(){this.context.destroy(),this.isDestroyed=!0}updateStatus(){if(this.isDestroyed)return void(this.status!==exports.DevbookStatus.Disconnected&&(this.status=exports.DevbookStatus.Disconnected));let e;switch(this.sessionStatus){case d.Disconnected:e=exports.DevbookStatus.Disconnected;break;case d.Connecting:e=exports.DevbookStatus.Connecting;break;case d.Connected:if(!this.isEnvReady){e=exports.DevbookStatus.Connecting;break}e=exports.DevbookStatus.Connected}this.status=e}}exports.Devbook=O,exports.useDevbook=function({env:e,debug:t}){const[n,i]=s.useState(),[o,r]=s.useState(exports.DevbookStatus.Disconnected),[a,c]=s.useState([]),[l,h]=s.useState([]),d=s.useCallback((e=>{n&&(h([]),c([]),n.runCmd(e))}),[n]),u=s.useCallback((e=>{n&&(h([]),c([]),n.runCode(e))}),[n]);return s.useEffect((function(){const n=new O({debug:t,env:e,onStatusChange(e){r(e)},onStderr(e){c((t=>[...t,e]))},onStdout(e){h((t=>[...t,e]))}});return h([]),c([]),i(n),()=>{n.destroy()}}),[e,t]),{stderr:a,stdout:l,runCmd:d,runCode:u,status:o}};
//# sourceMappingURL=index.js.map

@@ -25,3 +25,4 @@ export declare enum TRunner {

CmdExit = "RunningEnvironment.CmdExit",
RunningCmds = "RunningEnvironment.RunningCmds"
RunningCmds = "RunningEnvironment.RunningCmds",
RunCode = "RunningEnvironment.Run"
}

@@ -28,0 +29,0 @@ export declare enum TCodeCell {

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, } 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, } 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;
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;
payload: {

@@ -293,1 +293,18 @@ environmentID: string;

}
/**
* Sent to remote runner Runner to run a single command.
* Usually like so: `node index.js`.
*/
export interface RunningEnvironment_RunCode extends BaseRunningEnvironment {
type: TRunningEnvironment.RunCode;
payload: {
environmentID: string;
/**
* A unique ID that Runner received via the `RunningEnvironment_ExecCmd` message.
*/
executionID: string;
code: string;
filename: string;
command: string;
};
}
import { TemplateConfig } from 'src/common-ts/TemplateConfig';
/**
* Runtime environments that you can use with the Devbook VM.
* Runtime environments that you can use with the Devbooks' VMs.
*/

@@ -14,3 +14,4 @@ export declare enum Env {

toCommand: (code: string) => string;
fileExtension: string;
};
};

@@ -20,5 +20,5 @@ import { Env } from './constants';

/**
* Class representing connection to a VM that is used for running code and commands.
* Representation of a connection to a VM that is used for running code and commands.
*
* You can have multiple `Devbook` class instances -
* You can have multiple `Devbook` class instances connected to the same VM -
* instances with the same `env`({@link Env}) parameter passed to the constructor will share filesystem and process namespace.

@@ -48,7 +48,7 @@ */

/**
* Environment that this Devbook should use.
* Environment that this `Devbook` should use.
*
* This affects which runtime (NodeJS, etc...) will be available and used in the {@link Devbook.runCode} function.
*
* {@link Devbook} classes with different environments are isolated - each has their own filesystem and process namespace.
* `Devbook` instances with different environments are isolated - each has their own filesystem and process namespace.
*/

@@ -69,3 +69,3 @@ env: Env;

/**
* If this value is true then this Devbook will print detailed logs.
* If this value is true then this `Devbook` will print detailed logs.
*/

@@ -77,3 +77,3 @@ debug?: boolean;

*
* This {@link Devboook}'s VM shares filesystem and process namespace with other Devbook`s with the same `env`({@link Env}) passed to their constructors.
* This {@link Devboook}'s VM shares filesystem and process namespace with other `Devbook`'s with the same `env`({@link Env}) passed to their constructors.
*

@@ -86,3 +86,3 @@ * @param command Command to run

*
* This {@link Devboook}'s VM shares filesystem and process namespace with other Devbook`s with the same `env`({@link Env}) passed to their constructors.
* This {@link Devboook}'s VM shares filesystem and process namespace with other `Devbook`'s with the same `env`({@link Env}) passed to their constructors.
*

@@ -93,3 +93,3 @@ * @param code Code to run

/**
* Disconnect this Devbook from the VM.
* Disconnect this `Devbook` from the VM.
*/

@@ -96,0 +96,0 @@ destroy(): void;

@@ -18,9 +18,8 @@ import * as rws from 'src/common-ts/RunnerWebSocket';

private readonly opts;
private logger?;
get contextID(): string;
envs: RunningEnvironment[];
private unsubscribeConnHandler;
private readonly logger;
private get contextID();
private fsWriteSubscribers;
private envs;
private readonly unsubscribeConnHandler;
constructor(opts: EvaluationContextOpts);
handleConnectionOpen(): void;
handleConnectionClose(): void;
/**

@@ -32,17 +31,25 @@ * Restarts all context's objects to their default state.

destroy(): void;
private handleConnectionMessage;
deleteRunningEnvironment({ templateID }: {
templateID: string;
}): void;
createRunningEnvironment({ templateID }: {
executeCode({ templateID, executionID, code }: {
templateID: Env;
}): RunningEnvironment;
vmenv_handleStartAck(payload: rws.RunningEnvironment_StartAck['payload']): void;
vmenv_handleCmdOut(payload: rws.RunningEnvironment_CmdOut['payload']): void;
executionID: string;
code: string;
}): Promise<void>;
executeCommand({ templateID, executionID, command }: {
templateID: string;
templateID: Env;
executionID: string;
command: string;
}): void;
createRunningEnvironment({ templateID }: {
templateID: Env;
}): void;
private subscribeFSWrite;
private unsubscribeFSWrite;
private handleConnectionOpen;
private handleConnectionClose;
private handleConnectionMessage;
private vmenv_handleCmdExit;
private vmenv_handleFSEventWrite;
private vmenv_handleStartAck;
private vmenv_handleCmdOut;
}
export default EvaluationContext;

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

export { default as Devbook, DevbookStatus } from './devbook';
export { default as Devbook, DevbookStatus, } from './devbook';
export { Env } from './constants';
import RunningEnvironment from './runningEnvironment';
import * as ws from './ws';
import * as ws from './webSocket';
export { RunningEnvironment, ws, };
export { useDevbook } from './react';
export { Devbook, Env, DevbookStatus } from './core';
export { Devbook, Env, DevbookStatus, } from './core';

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

import{useState as e,useCallback as n,useEffect as t}from"react";var s;!function(e){e.NodeJS="nodejs-v16"}(s||(s={}));const i={"nodejs-v16":{id:"nodejs-v16",image:"us-central1-docker.pkg.dev/devbookhq/devbook-runner-templates/nodejs-v16:latest",root_dir:"/home/runner",code_cells_dir:"/home/runner/src",toCommand:e=>`node -e "${e}"`}};class o{constructor(e,n=!1){this.logID=e,this.isEnabled=n}id(){return"function"==typeof this.logID?this.logID():this.logID}log(...e){this.isEnabled&&console.log(`[${this.id()}]`,...e)}warn(...e){this.isEnabled&&console.warn(`[${this.id()}]`,...e)}error(...e){console.error(`[${this.id()} ERROR]`,...e)}}
import{useState as e,useCallback as n,useEffect as t}from"react";class s{constructor(e,n=!1){this.logID=e,this.isEnabled=n}id(){return"function"==typeof this.logID?this.logID():this.logID}log(...e){this.isEnabled&&console.log(`[${this.id()}]`,...e)}warn(...e){this.isEnabled&&console.warn(`[${this.id()}]`,...e)}error(...e){console.error(`[${this.id()} ERROR]`,...e)}}
/*! *****************************************************************************

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

PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */function r(e,n,t,s){return new(t||(t=Promise))((function(i,o){function r(e){try{a(s.next(e))}catch(e){o(e)}}function l(e){try{a(s.throw(e))}catch(e){o(e)}}function a(e){var n;e.done?i(e.value):(n=e.value,n instanceof t?n:new t((function(e){e(n)}))).then(r,l)}a((s=s.apply(e,n||[])).next())}))}function l(e){return new Promise((n=>setTimeout(n,e)))}var a,c,d;!function(e){e.Error="Runner.Error"}(a||(a={})),function(e){e.Start="RunningEnvironment.Start",e.StartAck="RunningEnvironment.StartAck",e.Eval="RunningEnvironment.Eval",e.FSEventCreate="RunningEnvironment.FSEventCreate",e.FSEventRemove="RunningEnvironment.FSEventRemove",e.FSEventWrite="RunningEnvironment.FSEventWrite",e.CreateDir="RunningEnvironment.CreateDir",e.ListDir="RunningEnvironment.ListDir",e.WriteFile="RunningEnvironment.WriteFile",e.GetFile="RunningEnvironment.GetFile",e.RemoveFile="RunningEnvironment.RemoveFile",e.DirContent="RunningEnvironment.DirContent",e.FileContent="RunningEnvironment.FileContent",e.Stdout="RunningEnvironment.Stdout",e.Stderr="RunningEnvironment.Stderr",e.ExecCmd="RunningEnvironment.ExecCmd",e.KillCmd="RunningEnvironment.KillCmd",e.ListRunningCmds="RunningEnvironment.ListRunningCmds",e.CmdOut="RunningEnvironment.CmdOut",e.CmdExit="RunningEnvironment.CmdExit",e.RunningCmds="RunningEnvironment.RunningCmds"}(c||(c={})),function(e){e.Error="CodeCell.Error"}(d||(d={}));const h={Runner:a,RunningEnvironment:c,CodeCell:d};class g{constructor(){this.url="wss://orchestrator.usedevbook.com",this.logger=new o("WebSocketConnection"),this.handlers=[]}get state(){var e;return null===(e=this.client)||void 0===e?void 0:e.readyState}get isClosed(){if(void 0!==this.client)return this.client.readyState===this.client.CLOSED}get isClosing(){if(void 0!==this.client)return this.client.readyState===this.client.CLOSING}get isOpen(){if(void 0!==this.client)return this.client.readyState===this.client.OPEN}get isConnecting(){if(void 0!==this.client)return this.client.readyState===this.client.CONNECTING}subscribeHandler(e){return this.handlers.push(e),()=>{this.handlers=this.handlers.filter((n=>n!==e))}}connect(e){(!this.client||this.client.readyState!==this.client.CONNECTING&&this.client.readyState!==this.client.OPEN)&&(e||this.sessionID?(e?(this.logger.log(`Will try to connect to session "${e}"`),this.sessionID=e):!e&&this.sessionID&&this.logger.log(`Will try to connect to previous session "${this.sessionID}"`),this.client=new WebSocket(`${this.url}/session/ws/${this.sessionID}`),this.client.onopen=()=>this.handleOpen(),this.client.onmessage=e=>{this.logger.log("Received (raw)",{msg:e}),this.handleMessage(e)},this.client.onerror=e=>this.handleError(e),this.client.onclose=e=>this.handleClose(e)):this.logger.error("Cannot connect, no session ID passed to the function and no session ID saved from the previous session"))}send(e){this.client&&this.client.readyState===this.client.OPEN?(this.logger.log("Send",e),this._send(e)):this.logger.warn("Trying to send a message while not being in the `OPEN` state or without established connection, message will be discarded",e)}close(){var e;this.logger.log("Closing connection"),null===(e=this.client)||void 0===e||e.close(1e3)}handleOpen(){var e;this.logger.log("Connection opened",{readyState:null===(e=this.client)||void 0===e?void 0:e.readyState}),this.handlers.forEach((e=>e.onOpen()))}_send(e){var n,t;null===(n=this.client)||void 0===n||n.send((t=e,JSON.stringify(t,(()=>{const e=new WeakSet;return(n,t)=>{if("object"==typeof t&&null!==t){if(e.has(t))return;e.add(t)}return t}})(),2)))}handleClose(e){return r(this,void 0,void 0,(function*(){this.logger.log("Connection closed",e),this.handlers.forEach((e=>e.onClose())),this.logger.log("Will try to reconnect in 3s"),yield l(3e3),this.connect()}))}handleError(e){var n;this.logger.error("Connection error",e),null===(n=this.client)||void 0===n||n.close()}handleMessage(e){if(!e.data)return void this.logger.error("Message has empty data field",e);const n=JSON.parse(e.data);if(!n.type)return void this.logger.error("Message has no type",n);const t=n;Object.values(h.RunningEnvironment).includes(t.type)||Object.values(h.Runner).includes(t.type)||Object.values(h.CodeCell).includes(t.type)?t.type!==h.Runner.Error?(this.logger.log("Received (parsed)",t),this.handlers.forEach((e=>e.onMessage(t)))):this.logger.error("Runner error",t):this.logger.error('Message "type" field has unexpected value',t)}}var u,v;!function(e){e.Ok="Ok",e.Terminated="Terminated"}(u||(u={}));class m{constructor(e,n=new Date){this.id=e,this.lastPing=n,this.logger=new o("RunnerSession"),this.url="https://orchestrator.usedevbook.com"}ping(){return r(this,void 0,void 0,(function*(){this.logger.log(`Pinging session "${this.id}"`);const e=JSON.stringify({sessionID:this.id});try{const n=yield fetch(`${this.url}/session/ping`,{method:"POST",headers:{"Content-Type":"application/json"},body:e}),t=yield n.json();if(!n.ok)throw this.logger.error(n.headers,t),new Error("Non-OK response when trying to ping active Runner session");if(t.status===u.Terminated)throw new Error(`[keepAlive]: Session '${this.id}' is terminated`);this.lastPing=new Date}catch(e){throw this.logger.error(e),new Error("Failed to ping active Runner session")}}))}}!function(e){e.Connected="Connected",e.Connecting="Connecting",e.Disconnected="Disconnected"}(v||(v={}));class C{constructor(e){this.conn=e,this.logger=new o("SessionManager"),this.url="https://orchestrator.usedevbook.com",this.isGettingSessionActive=!1,this.status=v.Disconnected,this.logger.log("Initialize"),this.getSession()}get cachedSessionID(){return sessionStorage.getItem("dbk_sdk_session_id")}set cachedSessionID(e){null===e?(this.logger.log("Cleared last sessionID"),sessionStorage.removeItem("dbk_sdk_session_id")):(this.logger.log(`Saved sessionID "${e}" as last sessionID`),sessionStorage.setItem("dbk_sdk_session_id",e))}reset(){this.logger.log("Reset"),this.status=v.Disconnected,this.cachedSessionID=null,this.conn.close(),this.session=void 0}getSession(){var e;return r(this,void 0,void 0,(function*(){if(!this.isGettingSessionActive)for(this.isGettingSessionActive=!0;;){this.status=v.Connecting;try{const n=this.cachedSessionID?`${this.url}/session/${this.cachedSessionID}`:`${this.url}/session`;this.cachedSessionID?this.logger.log(`Restoring old Runner session "${this.cachedSessionID}"`):this.logger.log("Acquiring new Runner session");const t=yield fetch(n),s=yield t.json();if(!t.ok){this.logger.error("Non-OK response when trying to ping active Runner session. Will try again in 3s",t.headers,s),yield l(3e3);continue}for(this.session=new m(s.sessionID),this.logger.log(`Acquired session "${this.session.id}"`),this.cachedSessionID=this.session.id,this.status=v.Connected,this.conn.connect(this.session.id),this.logger.log(`Started pinging session "${this.session.id}"`);this.session;)try{yield this.session.ping(),yield l(5e3)}catch(e){this.logger.error(`Failed to ping session "${this.session.id}"`,e);break}this.logger.log(`Stopped pinging session "${null===(e=this.session)||void 0===e?void 0:e.id}"`),this.session=void 0,this.status=v.Disconnected,this.conn.close()}catch(e){this.logger.error("Failed to acquire Runner session. Will try again in 3s",e),yield l(3e3)}}}))}}function p(e){return function(e){const n=Array.from(e).reduce(((e,n)=>0|31*e+n.charCodeAt(0)),0);return("0000000"+(n>>>0).toString(16)).slice(-8)}(e)}class D{constructor(e,n){this.contextID=e,this.templateID=n,this.isReady=!1,this.id=`${e}_${p(n)}`,this.template=i[this.templateID]}}function E(e,{environmentID:n,template:t}){const s={type:h.RunningEnvironment.Start,payload:{environmentID:n,template:t}};e.send(s)}class S{constructor(e){this.opts=e,this.envs=[],this.logger=new o("EvaluationContext",e.debug),this.unsubscribeConnHandler=this.opts.conn.subscribeHandler({onOpen:this.handleConnectionOpen.bind(this),onMessage:this.handleConnectionMessage.bind(this),onClose:this.handleConnectionClose.bind(this)}),this.opts.conn.isOpen&&this.handleConnectionOpen(),this.opts.conn.isClosed&&this.handleConnectionClose()}get contextID(){return this.opts.contextID}handleConnectionOpen(){var e,n;this.restart(),null===(n=(e=this.opts).onSessionChange)||void 0===n||n.call(e,{status:v.Connected})}handleConnectionClose(){var e,n;null===(n=(e=this.opts).onSessionChange)||void 0===n||n.call(e,{status:v.Connecting})}restart(){var e;return null===(e=this.logger)||void 0===e||e.log("Restart - session:",this.opts.conn.sessionID),this.envs.forEach((e=>{e.isReady=!1,E(this.opts.conn,{environmentID:e.id,template:e.template})}))}destroy(){var e;null===(e=this.logger)||void 0===e||e.log("Destroy"),this.envs=[],this.unsubscribeConnHandler()}handleConnectionMessage(e){var n,t;switch(null===(n=this.logger)||void 0===n||n.log("Handling message from remote Runner",{message:e}),e.type){case h.RunningEnvironment.StartAck:{const n=e;this.vmenv_handleStartAck(n.payload);break}case h.RunningEnvironment.CmdOut:{const n=e;this.vmenv_handleCmdOut(n.payload);break}default:null===(t=this.logger)||void 0===t||t.warn("Unknown message type",{message:e})}}deleteRunningEnvironment({templateID:e}){var n;null===(n=this.logger)||void 0===n||n.log('Handling "DeleteEnvironment"',{templateID:e}),this.envs=this.envs.filter((n=>n.templateID!==e))}createRunningEnvironment({templateID:e}){var n,t,s;null===(n=this.logger)||void 0===n||n.log('Handling "CreateEnvironment"',{templateID:e});const i=this.envs.find((n=>n.templateID===e));if(i)return i;const o=new D(this.contextID,e);return this.envs=[...this.envs,o],E(this.opts.conn,{environmentID:o.id,template:o.template}),null===(s=(t=this.opts).onEnvChange)||void 0===s||s.call(t,o),o}vmenv_handleStartAck(e){var n,t,s,i;null===(n=this.logger)||void 0===n||n.log('[vmenv] Handling "StartAck"',{payload:e});const o=this.envs.find((n=>n.id===e.environmentID));o?(o.isReady=!0,null===(i=(s=this.opts).onEnvChange)||void 0===i||i.call(s,o)):null===(t=this.logger)||void 0===t||t.warn("Environment not found",{payload:e})}vmenv_handleCmdOut(e){var n,t,s;null===(n=this.logger)||void 0===n||n.log('[vmenv] Handling "CmdOut"',e),null===(s=(t=this.opts).onCmdOut)||void 0===s||s.call(t,e)}executeCommand({templateID:e,executionID:n,command:t}){var s,i,o;null===(s=this.logger)||void 0===s||s.log("Exec shell code cell",{templateID:e,executionID:n,command:t});const r=this.envs.find((n=>n.templateID===e));r?r.isReady?function(e,{environmentID:n,executionID:t,command:s}){const i={type:h.RunningEnvironment.ExecCmd,payload:{environmentID:n,executionID:t,command:s}};e.send(i)}(this.opts.conn,{environmentID:r.id,executionID:n,command:t}):null===(o=this.logger)||void 0===o||o.error("Environment is not ready",{templateID:e,executionID:n,command:t}):null===(i=this.logger)||void 0===i||i.error("Environment not found",{templateID:e,executionID:n,command:t})}}class y{constructor(){this.logger=new o("Runner"),this.conn=new g,this.sessManager=new C(this.conn)}static get obj(){return y._obj||(y._obj=new y)}get session(){return this.sessManager.session}get status(){return this.sessManager.status}reset(){this.logger.log("Reset"),this.sessManager.reset()}createContext(e){return new S(Object.assign(Object.assign({},e),{conn:this.conn}))}__debug__loadNewSession(){this.logger.log("__debug__loadNewSession"),this.sessManager.reset()}}const R=(I="1234567890abcdefghijklmnopqrstuvwxyz",f=6,()=>{let e="",n=f;for(;n--;)e+=I[Math.random()*I.length|0];return e});var I,f,b;!function(e){e[e.Disconnected=0]="Disconnected",e[e.Connecting=1]="Connecting",e[e.Connected=2]="Connected"}(b||(b={}));class w{constructor(e){this.opts=e,this._isDestroyed=!1,this._isEnvReady=!1,this._sessionStatus=v.Disconnected,this._status=b.Disconnected;const n="default";this.contextID=n;const t=R();this.executionID=t;const s=e=>this.isEnvReady=e,i=e=>this.sessionStatus=e;this.context=y.obj.createContext({debug:e.debug,contextID:n,onEnvChange(e){s(e.isReady)},onSessionChange({status:e}){i(e)},onCmdOut(n){var s,i;n.executionID===t&&(void 0!==n.stdout&&(null===(s=e.onStdout)||void 0===s||s.call(e,n.stdout)),void 0!==n.stderr&&(null===(i=e.onStderr)||void 0===i||i.call(e,n.stderr)))}}),this.context.createRunningEnvironment({templateID:e.env})}get isDestroyed(){return this._isDestroyed}set isDestroyed(e){this._isDestroyed=e,this.updateStatus()}get isEnvReady(){return this._isEnvReady}set isEnvReady(e){this._isEnvReady=e,this.updateStatus()}get sessionStatus(){return this._sessionStatus}set sessionStatus(e){this._sessionStatus=e,this.updateStatus()}get status(){return this._status}set status(e){var n,t;this._status=e,null===(t=(n=this.opts).onStatusChange)||void 0===t||t.call(n,e)}runCmd(e){this.status!==b.Disconnected&&this.context.executeCommand({templateID:this.opts.env,executionID:this.executionID,command:e})}runCode(e){const n=i[this.opts.env].toCommand(e);this.runCmd(n)}destroy(){this.context.destroy(),this.isDestroyed=!0}updateStatus(){if(this.isDestroyed)return void(this.status!==b.Disconnected&&(this.status=b.Disconnected));let e;switch(this.sessionStatus){case v.Disconnected:e=b.Disconnected;break;case v.Connecting:e=b.Connecting;break;case v.Connected:if(!this.isEnvReady){e=b.Connecting;break}e=b.Connected}this.status=e}}function _({env:s,debug:i}){const[o,r]=e(),[l,a]=e(b.Disconnected),[c,d]=e([]),[h,g]=e([]),u=n((e=>{o&&(g([]),d([]),o.runCmd(e))}),[o]),v=n((e=>{o&&(g([]),d([]),o.runCode(e))}),[o]);return t((function(){const e=new w({debug:i,env:s,onStatusChange(e){a(e)},onStderr(e){d((n=>[...n,e]))},onStdout(e){g((n=>[...n,e]))}});return g([]),d([]),r(e),()=>{e.destroy()}}),[s,i]),{stderr:c,stdout:h,runCmd:u,runCode:v,status:l}}export{w as Devbook,b as DevbookStatus,s as Env,_ as useDevbook};
***************************************************************************** */function i(e,n,t,s){return new(t||(t=Promise))((function(i,o){function r(e){try{c(s.next(e))}catch(e){o(e)}}function a(e){try{c(s.throw(e))}catch(e){o(e)}}function c(e){var n;e.done?i(e.value):(n=e.value,n instanceof t?n:new t((function(e){e(n)}))).then(r,a)}c((s=s.apply(e,n||[])).next())}))}function o(e){return new Promise((n=>setTimeout(n,e)))}var r,a,c;!function(e){e.Error="Runner.Error"}(r||(r={})),function(e){e.Start="RunningEnvironment.Start",e.StartAck="RunningEnvironment.StartAck",e.Eval="RunningEnvironment.Eval",e.FSEventCreate="RunningEnvironment.FSEventCreate",e.FSEventRemove="RunningEnvironment.FSEventRemove",e.FSEventWrite="RunningEnvironment.FSEventWrite",e.CreateDir="RunningEnvironment.CreateDir",e.ListDir="RunningEnvironment.ListDir",e.WriteFile="RunningEnvironment.WriteFile",e.GetFile="RunningEnvironment.GetFile",e.RemoveFile="RunningEnvironment.RemoveFile",e.DirContent="RunningEnvironment.DirContent",e.FileContent="RunningEnvironment.FileContent",e.Stdout="RunningEnvironment.Stdout",e.Stderr="RunningEnvironment.Stderr",e.ExecCmd="RunningEnvironment.ExecCmd",e.KillCmd="RunningEnvironment.KillCmd",e.ListRunningCmds="RunningEnvironment.ListRunningCmds",e.CmdOut="RunningEnvironment.CmdOut",e.CmdExit="RunningEnvironment.CmdExit",e.RunningCmds="RunningEnvironment.RunningCmds",e.RunCode="RunningEnvironment.Run"}(a||(a={})),function(e){e.Error="CodeCell.Error"}(c||(c={}));const l={Runner:r,RunningEnvironment:a,CodeCell:c};var h;!function(e){e.NodeJS="nodejs-v16"}(h||(h={}));const d={"nodejs-v16":{id:"nodejs-v16",fileExtension:".js",image:"us-central1-docker.pkg.dev/devbookhq/devbook-runner-templates/nodejs-v16:latest",root_dir:"/home/runner",code_cells_dir:"/home/runner/src",toCommand:e=>`node "${e}"`}};class u{constructor(){this.url="wss://orchestrator.usedevbook.com",this.logger=new s("WebSocketConnection"),this.handlers=[]}get state(){var e;return null===(e=this.client)||void 0===e?void 0:e.readyState}get isClosed(){if(void 0!==this.client)return this.client.readyState===this.client.CLOSED}get isClosing(){if(void 0!==this.client)return this.client.readyState===this.client.CLOSING}get isOpen(){if(void 0!==this.client)return this.client.readyState===this.client.OPEN}get isConnecting(){if(void 0!==this.client)return this.client.readyState===this.client.CONNECTING}subscribeHandler(e){return this.handlers.push(e),()=>{this.handlers=this.handlers.filter((n=>n!==e))}}connect(e){(!this.client||this.client.readyState!==this.client.CONNECTING&&this.client.readyState!==this.client.OPEN)&&(e||this.sessionID?(e?(this.logger.log(`Will try to connect to session "${e}"`),this.sessionID=e):!e&&this.sessionID&&this.logger.log(`Will try to connect to previous session "${this.sessionID}"`),this.client=new WebSocket(`${this.url}/session/ws/${this.sessionID}`),this.client.onopen=()=>this.handleOpen(),this.client.onmessage=e=>{this.logger.log("Received (raw)",{msg:e}),this.handleMessage(e)},this.client.onerror=e=>this.handleError(e),this.client.onclose=e=>this.handleClose(e)):this.logger.error("Cannot connect, no session ID passed to the function and no session ID saved from the previous session"))}send(e){this.client&&this.client.readyState===this.client.OPEN?(this.logger.log("Send",e),this._send(e)):this.logger.warn("Trying to send a message while not being in the `OPEN` state or without established connection, message will be discarded",e)}close(){var e;this.logger.log("Closing connection"),null===(e=this.client)||void 0===e||e.close(1e3)}handleOpen(){var e;this.logger.log("Connection opened",{readyState:null===(e=this.client)||void 0===e?void 0:e.readyState}),this.handlers.forEach((e=>e.onOpen()))}_send(e){var n,t;null===(n=this.client)||void 0===n||n.send((t=e,JSON.stringify(t,(()=>{const e=new WeakSet;return(n,t)=>{if("object"==typeof t&&null!==t){if(e.has(t))return;e.add(t)}return t}})(),2)))}handleClose(e){return i(this,void 0,void 0,(function*(){this.logger.log("Connection closed",e),this.handlers.forEach((e=>e.onClose())),this.logger.log("Will try to reconnect in 3s"),yield o(3e3),this.connect()}))}handleError(e){var n;this.logger.error("Connection error",e),null===(n=this.client)||void 0===n||n.close()}handleMessage(e){if(!e.data)return void this.logger.error("Message has empty data field",e);const n=JSON.parse(e.data);if(!n.type)return void this.logger.error("Message has no type",n);const t=n;Object.values(l.RunningEnvironment).includes(t.type)||Object.values(l.Runner).includes(t.type)||Object.values(l.CodeCell).includes(t.type)?t.type!==l.Runner.Error?(this.logger.log("Received (parsed)",t),this.handlers.forEach((e=>e.onMessage(t)))):this.logger.error("Runner error",t):this.logger.error('Message "type" field has unexpected value',t)}}var g,v;!function(e){e.Ok="Ok",e.Terminated="Terminated"}(g||(g={}));class m{constructor(e,n=new Date){this.id=e,this.lastPing=n,this.logger=new s("RunnerSession"),this.url="https://orchestrator.usedevbook.com"}ping(){return i(this,void 0,void 0,(function*(){this.logger.log(`Pinging session "${this.id}"`);const e=JSON.stringify({sessionID:this.id});try{const n=yield fetch(`${this.url}/session/ping`,{method:"POST",headers:{"Content-Type":"application/json"},body:e}),t=yield n.json();if(!n.ok)throw this.logger.error(n.headers,t),new Error("Non-OK response when trying to ping active Runner session");if(t.status===g.Terminated)throw new Error(`[keepAlive]: Session '${this.id}' is terminated`);this.lastPing=new Date}catch(e){throw this.logger.error(e),new Error("Failed to ping active Runner session")}}))}}!function(e){e.Connected="Connected",e.Connecting="Connecting",e.Disconnected="Disconnected"}(v||(v={}));class p{constructor(e){this.conn=e,this.logger=new s("SessionManager"),this.url="https://orchestrator.usedevbook.com",this.isGettingSessionActive=!1,this.status=v.Disconnected,this.logger.log("Initialize"),this.getSession()}get cachedSessionID(){return sessionStorage.getItem("dbk_sdk_session_id")}set cachedSessionID(e){null===e?(this.logger.log("Cleared last sessionID"),sessionStorage.removeItem("dbk_sdk_session_id")):(this.logger.log(`Saved sessionID "${e}" as last sessionID`),sessionStorage.setItem("dbk_sdk_session_id",e))}reset(){this.logger.log("Reset"),this.status=v.Disconnected,this.cachedSessionID=null,this.conn.close(),this.session=void 0}getSession(){var e;return i(this,void 0,void 0,(function*(){if(!this.isGettingSessionActive)for(this.isGettingSessionActive=!0;;){this.status=v.Connecting;try{const n=this.cachedSessionID?`${this.url}/session/${this.cachedSessionID}`:`${this.url}/session`;this.cachedSessionID?this.logger.log(`Restoring old Runner session "${this.cachedSessionID}"`):this.logger.log("Acquiring new Runner session");const t=yield fetch(n),s=yield t.json();if(!t.ok){this.logger.error("Non-OK response when trying to ping active Runner session. Will try again in 3s",t.headers,s),yield o(3e3);continue}for(this.session=new m(s.sessionID),this.logger.log(`Acquired session "${this.session.id}"`),this.cachedSessionID=this.session.id,this.status=v.Connected,this.conn.connect(this.session.id),this.logger.log(`Started pinging session "${this.session.id}"`);this.session;)try{yield this.session.ping(),yield o(5e3)}catch(e){this.logger.error(`Failed to ping session "${this.session.id}"`,e);break}this.logger.log(`Stopped pinging session "${null===(e=this.session)||void 0===e?void 0:e.id}"`),this.session=void 0,this.status=v.Disconnected,this.conn.close()}catch(e){this.logger.error("Failed to acquire Runner session. Will try again in 3s",e),yield o(3e3)}}}))}}function f(e,n){for(var t=0,s=e.length-1;s>=0;s--){var i=e[s];"."===i?e.splice(s,1):".."===i?(e.splice(s,1),t++):t&&(e.splice(s,1),t--)}if(n)for(;t--;t)e.unshift("..");return e}var D=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/,C=function(e){return D.exec(e).slice(1)};function E(){for(var e="",n=!1,t=arguments.length-1;t>=-1&&!n;t--){var s=t>=0?arguments[t]:"/";if("string"!=typeof s)throw new TypeError("Arguments to path.resolve must be strings");s&&(e=s+"/"+e,n="/"===s.charAt(0))}return(n?"/":"")+(e=f(b(e.split("/"),(function(e){return!!e})),!n).join("/"))||"."}function S(e){var n=y(e),t="/"===x(e,-1);return(e=f(b(e.split("/"),(function(e){return!!e})),!n).join("/"))||n||(e="."),e&&t&&(e+="/"),(n?"/":"")+e}function y(e){return"/"===e.charAt(0)}var I={extname:function(e){return C(e)[3]},basename:function(e,n){var t=C(e)[2];return n&&t.substr(-1*n.length)===n&&(t=t.substr(0,t.length-n.length)),t},dirname:function(e){var n=C(e),t=n[0],s=n[1];return t||s?(s&&(s=s.substr(0,s.length-1)),t+s):"."},sep:"/",delimiter:":",relative:function(e,n){function t(e){for(var n=0;n<e.length&&""===e[n];n++);for(var t=e.length-1;t>=0&&""===e[t];t--);return n>t?[]:e.slice(n,t-n+1)}e=E(e).substr(1),n=E(n).substr(1);for(var s=t(e.split("/")),i=t(n.split("/")),o=Math.min(s.length,i.length),r=o,a=0;a<o;a++)if(s[a]!==i[a]){r=a;break}var c=[];for(a=r;a<s.length;a++)c.push("..");return(c=c.concat(i.slice(r))).join("/")},join:function(){var e=Array.prototype.slice.call(arguments,0);return S(b(e,(function(e,n){if("string"!=typeof e)throw new TypeError("Arguments to path.join must be strings");return e})).join("/"))},isAbsolute:y,normalize:S,resolve:E};function b(e,n){if(e.filter)return e.filter(n);for(var t=[],s=0;s<e.length;s++)n(e[s],s,e)&&t.push(e[s]);return t}var R,x="b"==="ab".substr(-1)?function(e,n,t){return e.substr(n,t)}:function(e,n,t){return n<0&&(n=e.length+n),e.substr(n,t)};function w(e){return function(e){const n=Array.from(e).reduce(((e,n)=>0|31*e+n.charCodeAt(0)),0);return("0000000"+(n>>>0).toString(16)).slice(-8)}(e)}class _{constructor(e,n){this.contextID=e,this.templateID=n,this.isReady=!1,this.id=`${e}_${w(n)}`,this.template=d[this.templateID]}}function O(e,{environmentID:n,template:t}){const s={type:l.RunningEnvironment.Start,payload:{environmentID:n,template:t}};e.send(s)}function k(e,{environmentID:n,executionID:t,command:s}){const i={type:l.RunningEnvironment.ExecCmd,payload:{environmentID:n,executionID:t,command:s}};e.send(i)}class W{constructor(e){this.opts=e,this.fsWriteSubscribers=[],this.envs=[],this.logger=new s("EvaluationContext",e.debug),this.unsubscribeConnHandler=this.opts.conn.subscribeHandler({onOpen:this.handleConnectionOpen.bind(this),onMessage:this.handleConnectionMessage.bind(this),onClose:this.handleConnectionClose.bind(this)}),this.opts.conn.isOpen&&this.handleConnectionOpen(),this.opts.conn.isClosed&&this.handleConnectionClose()}get contextID(){return this.opts.contextID}restart(){return this.logger.log("Restart",this.opts.conn.sessionID),this.envs.forEach((e=>{e.isReady=!1,O(this.opts.conn,{environmentID:e.id,template:e.template})}))}destroy(){this.logger.log("Destroy"),this.unsubscribeConnHandler(),this.envs=[],this.fsWriteSubscribers=[]}executeCode({templateID:e,executionID:n,code:t}){return i(this,void 0,void 0,(function*(){this.logger.log("Execute code",{templateID:e,executionID:n});const s=this.envs.find((n=>n.templateID===e));if(!s)return void this.logger.error("Environment not found",{templateID:e,executionID:n});if(!s.isReady)return void this.logger.error("Environment is not ready",{templateID:e,executionID:n});const i=d[e].fileExtension,o=`${n}${i}`,r=I.join("/src",o);let a;const c=new Promise(((e,n)=>{a=e,setTimeout((()=>{n()}),1e4)})),h=e=>{e.path.endsWith(r)&&a()};this.subscribeFSWrite(h),function(e,{environmentID:n,path:t,content:s}){const i={type:l.RunningEnvironment.WriteFile,payload:{environmentID:n,path:t,content:s}};e.send(i)}(this.opts.conn,{environmentID:s.id,path:r,content:t});try{yield c}catch(e){return void this.logger.error(`File ${r} not written to VM`)}finally{this.unsubscribeFSWrite(h)}const u=I.join(d[e].root_dir,r),g=d[e].toCommand(u);k(this.opts.conn,{environmentID:s.id,executionID:n,command:g})}))}executeCommand({templateID:e,executionID:n,command:t}){this.logger.log("Execute shell command",{templateID:e,executionID:n,command:t});const s=this.envs.find((n=>n.templateID===e));s?s.isReady?k(this.opts.conn,{environmentID:s.id,executionID:n,command:t}):this.logger.error("Environment is not ready",{templateID:e,executionID:n,command:t}):this.logger.error("Environment not found",{templateID:e,executionID:n,command:t})}createRunningEnvironment({templateID:e}){var n,t;this.logger.log("Creating running environment",{templateID:e});if(this.envs.find((n=>n.templateID===e)))return;const s=new _(this.contextID,e);this.envs=[...this.envs,s],O(this.opts.conn,{environmentID:s.id,template:s.template}),null===(t=(n=this.opts).onEnvChange)||void 0===t||t.call(n,s)}subscribeFSWrite(e){this.fsWriteSubscribers.push(e)}unsubscribeFSWrite(e){this.fsWriteSubscribers=this.fsWriteSubscribers.filter((n=>n!==e))}handleConnectionOpen(){var e,n;this.restart(),null===(n=(e=this.opts).onSessionChange)||void 0===n||n.call(e,{status:v.Connected})}handleConnectionClose(){var e,n;null===(n=(e=this.opts).onSessionChange)||void 0===n||n.call(e,{status:v.Connecting})}handleConnectionMessage(e){switch(this.logger.log("Handling message from remote Runner",{message:e}),e.type){case l.RunningEnvironment.StartAck:{const n=e;this.vmenv_handleStartAck(n.payload);break}case l.RunningEnvironment.CmdOut:{const n=e;this.vmenv_handleCmdOut(n.payload);break}case l.RunningEnvironment.CmdExit:{const n=e;this.vmenv_handleCmdExit(n.payload);break}case l.RunningEnvironment.FSEventWrite:{const n=e;this.vmenv_handleFSEventWrite(n.payload);break}default:this.logger.warn("Unknown message type",{message:e})}}vmenv_handleCmdExit(e){var n,t;void 0!==e.error&&(null===(t=(n=this.opts).onCmdOut)||void 0===t||t.call(n,{environmentID:e.environmentID,executionID:e.executionID,stderr:e.error}))}vmenv_handleFSEventWrite(e){this.logger.log('[vmenv] Handling "FSEventWrite"',e);this.envs.find((n=>n.id===e.environmentID))?this.fsWriteSubscribers.forEach((n=>n(e))):this.logger.warn("Environment not found",{payload:e})}vmenv_handleStartAck(e){var n,t;this.logger.log('[vmenv] Handling "StartAck"',{payload:e});const s=this.envs.find((n=>n.id===e.environmentID));s?(s.isReady=!0,null===(t=(n=this.opts).onEnvChange)||void 0===t||t.call(n,s)):this.logger.warn("Environment not found",{payload:e})}vmenv_handleCmdOut(e){var n,t;this.logger.log('[vmenv] Handling "CmdOut"',e),null===(t=(n=this.opts).onCmdOut)||void 0===t||t.call(n,e)}}class F{constructor(){this.logger=new s("Runner"),this.conn=new u,this.sessManager=new p(this.conn)}static get obj(){return F._obj||(F._obj=new F)}get session(){return this.sessManager.session}get status(){return this.sessManager.status}reset(){this.logger.log("Reset"),this.sessManager.reset()}createContext(e){return new W(Object.assign(Object.assign({},e),{conn:this.conn}))}__debug__loadNewSession(){this.logger.log("__debug__loadNewSession"),this.sessManager.reset()}}!function(e){e[e.Disconnected=0]="Disconnected",e[e.Connecting=1]="Connecting",e[e.Connected=2]="Connected"}(R||(R={}));class j{constructor(e){this.opts=e,this._isDestroyed=!1,this._isEnvReady=!1,this._sessionStatus=v.Disconnected,this._status=R.Disconnected;const n="default";this.contextID=n;this.executionID="def";const t=e=>this.isEnvReady=e,s=e=>this.sessionStatus=e;this.context=F.obj.createContext({debug:e.debug,contextID:n,onEnvChange(e){t(e.isReady)},onSessionChange({status:e}){s(e)},onCmdOut(n){var t,s;"def"===n.executionID&&(void 0!==n.stdout&&(null===(t=e.onStdout)||void 0===t||t.call(e,n.stdout)),void 0!==n.stderr&&(null===(s=e.onStderr)||void 0===s||s.call(e,n.stderr)))}}),this.context.createRunningEnvironment({templateID:e.env})}get isDestroyed(){return this._isDestroyed}set isDestroyed(e){this._isDestroyed=e,this.updateStatus()}get isEnvReady(){return this._isEnvReady}set isEnvReady(e){this._isEnvReady=e,this.updateStatus()}get sessionStatus(){return this._sessionStatus}set sessionStatus(e){this._sessionStatus=e,this.updateStatus()}get status(){return this._status}set status(e){var n,t;this._status=e,null===(t=(n=this.opts).onStatusChange)||void 0===t||t.call(n,e)}runCmd(e){this.status!==R.Disconnected&&this.context.executeCommand({templateID:this.opts.env,executionID:this.executionID,command:e})}runCode(e){this.status!==R.Disconnected&&this.context.executeCode({templateID:this.opts.env,executionID:this.executionID,code:e})}destroy(){this.context.destroy(),this.isDestroyed=!0}updateStatus(){if(this.isDestroyed)return void(this.status!==R.Disconnected&&(this.status=R.Disconnected));let e;switch(this.sessionStatus){case v.Disconnected:e=R.Disconnected;break;case v.Connecting:e=R.Connecting;break;case v.Connected:if(!this.isEnvReady){e=R.Connecting;break}e=R.Connected}this.status=e}}function $({env:s,debug:i}){const[o,r]=e(),[a,c]=e(R.Disconnected),[l,h]=e([]),[d,u]=e([]),g=n((e=>{o&&(u([]),h([]),o.runCmd(e))}),[o]),v=n((e=>{o&&(u([]),h([]),o.runCode(e))}),[o]);return t((function(){const e=new j({debug:i,env:s,onStatusChange(e){c(e)},onStderr(e){h((n=>[...n,e]))},onStdout(e){u((n=>[...n,e]))}});return u([]),h([]),r(e),()=>{e.destroy()}}),[s,i]),{stderr:l,stdout:d,runCmd:g,runCode:v,status:a}}export{j as Devbook,R as DevbookStatus,h as Env,$ as useDevbook};
//# sourceMappingURL=index.js.map

@@ -25,3 +25,4 @@ export declare enum TRunner {

CmdExit = "RunningEnvironment.CmdExit",
RunningCmds = "RunningEnvironment.RunningCmds"
RunningCmds = "RunningEnvironment.RunningCmds",
RunCode = "RunningEnvironment.Run"
}

@@ -28,0 +29,0 @@ export declare enum TCodeCell {

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, } 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, } 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;
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;
payload: {

@@ -293,1 +293,18 @@ environmentID: string;

}
/**
* Sent to remote runner Runner to run a single command.
* Usually like so: `node index.js`.
*/
export interface RunningEnvironment_RunCode extends BaseRunningEnvironment {
type: TRunningEnvironment.RunCode;
payload: {
environmentID: string;
/**
* A unique ID that Runner received via the `RunningEnvironment_ExecCmd` message.
*/
executionID: string;
code: string;
filename: string;
command: string;
};
}
import { TemplateConfig } from 'src/common-ts/TemplateConfig';
/**
* Runtime environments that you can use with the Devbook VM.
* Runtime environments that you can use with the Devbooks' VMs.
*/

@@ -14,3 +14,4 @@ export declare enum Env {

toCommand: (code: string) => string;
fileExtension: string;
};
};

@@ -20,5 +20,5 @@ import { Env } from './constants';

/**
* Class representing connection to a VM that is used for running code and commands.
* Representation of a connection to a VM that is used for running code and commands.
*
* You can have multiple `Devbook` class instances -
* You can have multiple `Devbook` class instances connected to the same VM -
* instances with the same `env`({@link Env}) parameter passed to the constructor will share filesystem and process namespace.

@@ -48,7 +48,7 @@ */

/**
* Environment that this Devbook should use.
* Environment that this `Devbook` should use.
*
* This affects which runtime (NodeJS, etc...) will be available and used in the {@link Devbook.runCode} function.
*
* {@link Devbook} classes with different environments are isolated - each has their own filesystem and process namespace.
* `Devbook` instances with different environments are isolated - each has their own filesystem and process namespace.
*/

@@ -69,3 +69,3 @@ env: Env;

/**
* If this value is true then this Devbook will print detailed logs.
* If this value is true then this `Devbook` will print detailed logs.
*/

@@ -77,3 +77,3 @@ debug?: boolean;

*
* This {@link Devboook}'s VM shares filesystem and process namespace with other Devbook`s with the same `env`({@link Env}) passed to their constructors.
* This {@link Devboook}'s VM shares filesystem and process namespace with other `Devbook`'s with the same `env`({@link Env}) passed to their constructors.
*

@@ -86,3 +86,3 @@ * @param command Command to run

*
* This {@link Devboook}'s VM shares filesystem and process namespace with other Devbook`s with the same `env`({@link Env}) passed to their constructors.
* This {@link Devboook}'s VM shares filesystem and process namespace with other `Devbook`'s with the same `env`({@link Env}) passed to their constructors.
*

@@ -93,3 +93,3 @@ * @param code Code to run

/**
* Disconnect this Devbook from the VM.
* Disconnect this `Devbook` from the VM.
*/

@@ -96,0 +96,0 @@ destroy(): void;

@@ -18,9 +18,8 @@ import * as rws from 'src/common-ts/RunnerWebSocket';

private readonly opts;
private logger?;
get contextID(): string;
envs: RunningEnvironment[];
private unsubscribeConnHandler;
private readonly logger;
private get contextID();
private fsWriteSubscribers;
private envs;
private readonly unsubscribeConnHandler;
constructor(opts: EvaluationContextOpts);
handleConnectionOpen(): void;
handleConnectionClose(): void;
/**

@@ -32,17 +31,25 @@ * Restarts all context's objects to their default state.

destroy(): void;
private handleConnectionMessage;
deleteRunningEnvironment({ templateID }: {
templateID: string;
}): void;
createRunningEnvironment({ templateID }: {
executeCode({ templateID, executionID, code }: {
templateID: Env;
}): RunningEnvironment;
vmenv_handleStartAck(payload: rws.RunningEnvironment_StartAck['payload']): void;
vmenv_handleCmdOut(payload: rws.RunningEnvironment_CmdOut['payload']): void;
executionID: string;
code: string;
}): Promise<void>;
executeCommand({ templateID, executionID, command }: {
templateID: string;
templateID: Env;
executionID: string;
command: string;
}): void;
createRunningEnvironment({ templateID }: {
templateID: Env;
}): void;
private subscribeFSWrite;
private unsubscribeFSWrite;
private handleConnectionOpen;
private handleConnectionClose;
private handleConnectionMessage;
private vmenv_handleCmdExit;
private vmenv_handleFSEventWrite;
private vmenv_handleStartAck;
private vmenv_handleCmdOut;
}
export default EvaluationContext;

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

export { default as Devbook, DevbookStatus } from './devbook';
export { default as Devbook, DevbookStatus, } from './devbook';
export { Env } from './constants';
import RunningEnvironment from './runningEnvironment';
import * as ws from './ws';
import * as ws from './webSocket';
export { RunningEnvironment, ws, };
export { useDevbook } from './react';
export { Devbook, Env, DevbookStatus } from './core';
export { Devbook, Env, DevbookStatus, } from './core';

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

!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self)["@devbookhq/sdk"]={},e.react)}(this,(function(e,n){"use strict";const t="orchestrator.usedevbook.com",s="dbk_sdk_session_id",i=3e3;e.Env=void 0,(e.Env||(e.Env={})).NodeJS="nodejs-v16";const o={"nodejs-v16":{id:"nodejs-v16",image:"us-central1-docker.pkg.dev/devbookhq/devbook-runner-templates/nodejs-v16:latest",root_dir:"/home/runner",code_cells_dir:"/home/runner/src",toCommand:e=>`node -e "${e}"`}};class r{constructor(e,n=!1){this.logID=e,this.isEnabled=n}id(){return"function"==typeof this.logID?this.logID():this.logID}log(...e){this.isEnabled&&console.log(`[${this.id()}]`,...e)}warn(...e){this.isEnabled&&console.warn(`[${this.id()}]`,...e)}error(...e){console.error(`[${this.id()} ERROR]`,...e)}}
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self)["@devbookhq/sdk"]={},e.react)}(this,(function(e,n){"use strict";class t{constructor(e,n=!1){this.logID=e,this.isEnabled=n}id(){return"function"==typeof this.logID?this.logID():this.logID}log(...e){this.isEnabled&&console.log(`[${this.id()}]`,...e)}warn(...e){this.isEnabled&&console.warn(`[${this.id()}]`,...e)}error(...e){console.error(`[${this.id()} ERROR]`,...e)}}
/*! *****************************************************************************

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

PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */function a(e,n,t,s){return new(t||(t=Promise))((function(i,o){function r(e){try{l(s.next(e))}catch(e){o(e)}}function a(e){try{l(s.throw(e))}catch(e){o(e)}}function l(e){var n;e.done?i(e.value):(n=e.value,n instanceof t?n:new t((function(e){e(n)}))).then(r,a)}l((s=s.apply(e,n||[])).next())}))}function l(e){return new Promise((n=>setTimeout(n,e)))}var c,d,h;!function(e){e.Error="Runner.Error"}(c||(c={})),function(e){e.Start="RunningEnvironment.Start",e.StartAck="RunningEnvironment.StartAck",e.Eval="RunningEnvironment.Eval",e.FSEventCreate="RunningEnvironment.FSEventCreate",e.FSEventRemove="RunningEnvironment.FSEventRemove",e.FSEventWrite="RunningEnvironment.FSEventWrite",e.CreateDir="RunningEnvironment.CreateDir",e.ListDir="RunningEnvironment.ListDir",e.WriteFile="RunningEnvironment.WriteFile",e.GetFile="RunningEnvironment.GetFile",e.RemoveFile="RunningEnvironment.RemoveFile",e.DirContent="RunningEnvironment.DirContent",e.FileContent="RunningEnvironment.FileContent",e.Stdout="RunningEnvironment.Stdout",e.Stderr="RunningEnvironment.Stderr",e.ExecCmd="RunningEnvironment.ExecCmd",e.KillCmd="RunningEnvironment.KillCmd",e.ListRunningCmds="RunningEnvironment.ListRunningCmds",e.CmdOut="RunningEnvironment.CmdOut",e.CmdExit="RunningEnvironment.CmdExit",e.RunningCmds="RunningEnvironment.RunningCmds"}(d||(d={})),function(e){e.Error="CodeCell.Error"}(h||(h={}));const u={Runner:c,RunningEnvironment:d,CodeCell:h};class g{constructor(){this.url=`wss://${t}`,this.logger=new r("WebSocketConnection"),this.handlers=[]}get state(){var e;return null===(e=this.client)||void 0===e?void 0:e.readyState}get isClosed(){if(void 0!==this.client)return this.client.readyState===this.client.CLOSED}get isClosing(){if(void 0!==this.client)return this.client.readyState===this.client.CLOSING}get isOpen(){if(void 0!==this.client)return this.client.readyState===this.client.OPEN}get isConnecting(){if(void 0!==this.client)return this.client.readyState===this.client.CONNECTING}subscribeHandler(e){return this.handlers.push(e),()=>{this.handlers=this.handlers.filter((n=>n!==e))}}connect(e){(!this.client||this.client.readyState!==this.client.CONNECTING&&this.client.readyState!==this.client.OPEN)&&(e||this.sessionID?(e?(this.logger.log(`Will try to connect to session "${e}"`),this.sessionID=e):!e&&this.sessionID&&this.logger.log(`Will try to connect to previous session "${this.sessionID}"`),this.client=new WebSocket(`${this.url}/session/ws/${this.sessionID}`),this.client.onopen=()=>this.handleOpen(),this.client.onmessage=e=>{this.logger.log("Received (raw)",{msg:e}),this.handleMessage(e)},this.client.onerror=e=>this.handleError(e),this.client.onclose=e=>this.handleClose(e)):this.logger.error("Cannot connect, no session ID passed to the function and no session ID saved from the previous session"))}send(e){this.client&&this.client.readyState===this.client.OPEN?(this.logger.log("Send",e),this._send(e)):this.logger.warn("Trying to send a message while not being in the `OPEN` state or without established connection, message will be discarded",e)}close(){var e;this.logger.log("Closing connection"),null===(e=this.client)||void 0===e||e.close(1e3)}handleOpen(){var e;this.logger.log("Connection opened",{readyState:null===(e=this.client)||void 0===e?void 0:e.readyState}),this.handlers.forEach((e=>e.onOpen()))}_send(e){var n,t;null===(n=this.client)||void 0===n||n.send((t=e,JSON.stringify(t,(()=>{const e=new WeakSet;return(n,t)=>{if("object"==typeof t&&null!==t){if(e.has(t))return;e.add(t)}return t}})(),2)))}handleClose(e){return a(this,void 0,void 0,(function*(){this.logger.log("Connection closed",e),this.handlers.forEach((e=>e.onClose())),this.logger.log("Will try to reconnect in 3s"),yield l(3e3),this.connect()}))}handleError(e){var n;this.logger.error("Connection error",e),null===(n=this.client)||void 0===n||n.close()}handleMessage(e){if(!e.data)return void this.logger.error("Message has empty data field",e);const n=JSON.parse(e.data);if(!n.type)return void this.logger.error("Message has no type",n);const t=n;Object.values(u.RunningEnvironment).includes(t.type)||Object.values(u.Runner).includes(t.type)||Object.values(u.CodeCell).includes(t.type)?t.type!==u.Runner.Error?(this.logger.log("Received (parsed)",t),this.handlers.forEach((e=>e.onMessage(t)))):this.logger.error("Runner error",t):this.logger.error('Message "type" field has unexpected value',t)}}var v,m;!function(e){e.Ok="Ok",e.Terminated="Terminated"}(v||(v={}));class p{constructor(e,n=new Date){this.id=e,this.lastPing=n,this.logger=new r("RunnerSession"),this.url=`https://${t}`}ping(){return a(this,void 0,void 0,(function*(){this.logger.log(`Pinging session "${this.id}"`);const e=JSON.stringify({sessionID:this.id});try{const n=yield fetch(`${this.url}/session/ping`,{method:"POST",headers:{"Content-Type":"application/json"},body:e}),t=yield n.json();if(!n.ok)throw this.logger.error(n.headers,t),new Error("Non-OK response when trying to ping active Runner session");if(t.status===v.Terminated)throw new Error(`[keepAlive]: Session '${this.id}' is terminated`);this.lastPing=new Date}catch(e){throw this.logger.error(e),new Error("Failed to ping active Runner session")}}))}}!function(e){e.Connected="Connected",e.Connecting="Connecting",e.Disconnected="Disconnected"}(m||(m={}));class D{constructor(e){this.conn=e,this.logger=new r("SessionManager"),this.url=`https://${t}`,this.isGettingSessionActive=!1,this.status=m.Disconnected,this.logger.log("Initialize"),this.getSession()}get cachedSessionID(){return sessionStorage.getItem(s)}set cachedSessionID(e){null===e?(this.logger.log("Cleared last sessionID"),sessionStorage.removeItem(s)):(this.logger.log(`Saved sessionID "${e}" as last sessionID`),sessionStorage.setItem(s,e))}reset(){this.logger.log("Reset"),this.status=m.Disconnected,this.cachedSessionID=null,this.conn.close(),this.session=void 0}getSession(){var e;return a(this,void 0,void 0,(function*(){if(!this.isGettingSessionActive)for(this.isGettingSessionActive=!0;;){this.status=m.Connecting;try{const n=this.cachedSessionID?`${this.url}/session/${this.cachedSessionID}`:`${this.url}/session`;this.cachedSessionID?this.logger.log(`Restoring old Runner session "${this.cachedSessionID}"`):this.logger.log("Acquiring new Runner session");const t=yield fetch(n),s=yield t.json();if(!t.ok){this.logger.error("Non-OK response when trying to ping active Runner session. Will try again in 3s",t.headers,s),yield l(i);continue}for(this.session=new p(s.sessionID),this.logger.log(`Acquired session "${this.session.id}"`),this.cachedSessionID=this.session.id,this.status=m.Connected,this.conn.connect(this.session.id),this.logger.log(`Started pinging session "${this.session.id}"`);this.session;)try{yield this.session.ping(),yield l(5e3)}catch(e){this.logger.error(`Failed to ping session "${this.session.id}"`,e);break}this.logger.log(`Stopped pinging session "${null===(e=this.session)||void 0===e?void 0:e.id}"`),this.session=void 0,this.status=m.Disconnected,this.conn.close()}catch(e){this.logger.error("Failed to acquire Runner session. Will try again in 3s",e),yield l(i)}}}))}}function C(e){return function(e){const n=Array.from(e).reduce(((e,n)=>0|31*e+n.charCodeAt(0)),0);return("0000000"+(n>>>0).toString(16)).slice(-8)}(e)}class S{constructor(e,n){this.contextID=e,this.templateID=n,this.isReady=!1,this.id=`${e}_${C(n)}`,this.template=o[this.templateID]}}function y(e,{environmentID:n,template:t}){const s={type:u.RunningEnvironment.Start,payload:{environmentID:n,template:t}};e.send(s)}class E{constructor(e){this.opts=e,this.envs=[],this.logger=new r("EvaluationContext",e.debug),this.unsubscribeConnHandler=this.opts.conn.subscribeHandler({onOpen:this.handleConnectionOpen.bind(this),onMessage:this.handleConnectionMessage.bind(this),onClose:this.handleConnectionClose.bind(this)}),this.opts.conn.isOpen&&this.handleConnectionOpen(),this.opts.conn.isClosed&&this.handleConnectionClose()}get contextID(){return this.opts.contextID}handleConnectionOpen(){var e,n;this.restart(),null===(n=(e=this.opts).onSessionChange)||void 0===n||n.call(e,{status:m.Connected})}handleConnectionClose(){var e,n;null===(n=(e=this.opts).onSessionChange)||void 0===n||n.call(e,{status:m.Connecting})}restart(){var e;return null===(e=this.logger)||void 0===e||e.log("Restart - session:",this.opts.conn.sessionID),this.envs.forEach((e=>{e.isReady=!1,y(this.opts.conn,{environmentID:e.id,template:e.template})}))}destroy(){var e;null===(e=this.logger)||void 0===e||e.log("Destroy"),this.envs=[],this.unsubscribeConnHandler()}handleConnectionMessage(e){var n,t;switch(null===(n=this.logger)||void 0===n||n.log("Handling message from remote Runner",{message:e}),e.type){case u.RunningEnvironment.StartAck:{const n=e;this.vmenv_handleStartAck(n.payload);break}case u.RunningEnvironment.CmdOut:{const n=e;this.vmenv_handleCmdOut(n.payload);break}default:null===(t=this.logger)||void 0===t||t.warn("Unknown message type",{message:e})}}deleteRunningEnvironment({templateID:e}){var n;null===(n=this.logger)||void 0===n||n.log('Handling "DeleteEnvironment"',{templateID:e}),this.envs=this.envs.filter((n=>n.templateID!==e))}createRunningEnvironment({templateID:e}){var n,t,s;null===(n=this.logger)||void 0===n||n.log('Handling "CreateEnvironment"',{templateID:e});const i=this.envs.find((n=>n.templateID===e));if(i)return i;const o=new S(this.contextID,e);return this.envs=[...this.envs,o],y(this.opts.conn,{environmentID:o.id,template:o.template}),null===(s=(t=this.opts).onEnvChange)||void 0===s||s.call(t,o),o}vmenv_handleStartAck(e){var n,t,s,i;null===(n=this.logger)||void 0===n||n.log('[vmenv] Handling "StartAck"',{payload:e});const o=this.envs.find((n=>n.id===e.environmentID));o?(o.isReady=!0,null===(i=(s=this.opts).onEnvChange)||void 0===i||i.call(s,o)):null===(t=this.logger)||void 0===t||t.warn("Environment not found",{payload:e})}vmenv_handleCmdOut(e){var n,t,s;null===(n=this.logger)||void 0===n||n.log('[vmenv] Handling "CmdOut"',e),null===(s=(t=this.opts).onCmdOut)||void 0===s||s.call(t,e)}executeCommand({templateID:e,executionID:n,command:t}){var s,i,o;null===(s=this.logger)||void 0===s||s.log("Exec shell code cell",{templateID:e,executionID:n,command:t});const r=this.envs.find((n=>n.templateID===e));r?r.isReady?function(e,{environmentID:n,executionID:t,command:s}){const i={type:u.RunningEnvironment.ExecCmd,payload:{environmentID:n,executionID:t,command:s}};e.send(i)}(this.opts.conn,{environmentID:r.id,executionID:n,command:t}):null===(o=this.logger)||void 0===o||o.error("Environment is not ready",{templateID:e,executionID:n,command:t}):null===(i=this.logger)||void 0===i||i.error("Environment not found",{templateID:e,executionID:n,command:t})}}class f{constructor(){this.logger=new r("Runner"),this.conn=new g,this.sessManager=new D(this.conn)}static get obj(){return f._obj||(f._obj=new f)}get session(){return this.sessManager.session}get status(){return this.sessManager.status}reset(){this.logger.log("Reset"),this.sessManager.reset()}createContext(e){return new E(Object.assign(Object.assign({},e),{conn:this.conn}))}__debug__loadNewSession(){this.logger.log("__debug__loadNewSession"),this.sessManager.reset()}}const R=(I="1234567890abcdefghijklmnopqrstuvwxyz",b=6,()=>{let e="",n=b;for(;n--;)e+=I[Math.random()*I.length|0];return e});var I,b,k;e.DevbookStatus=void 0,(k=e.DevbookStatus||(e.DevbookStatus={}))[k.Disconnected=0]="Disconnected",k[k.Connecting=1]="Connecting",k[k.Connected=2]="Connected";class w{constructor(n){this.opts=n,this._isDestroyed=!1,this._isEnvReady=!1,this._sessionStatus=m.Disconnected,this._status=e.DevbookStatus.Disconnected;const t="default";this.contextID=t;const s=R();this.executionID=s;const i=e=>this.isEnvReady=e,o=e=>this.sessionStatus=e;this.context=f.obj.createContext({debug:n.debug,contextID:t,onEnvChange(e){i(e.isReady)},onSessionChange({status:e}){o(e)},onCmdOut(e){var t,i;e.executionID===s&&(void 0!==e.stdout&&(null===(t=n.onStdout)||void 0===t||t.call(n,e.stdout)),void 0!==e.stderr&&(null===(i=n.onStderr)||void 0===i||i.call(n,e.stderr)))}}),this.context.createRunningEnvironment({templateID:n.env})}get isDestroyed(){return this._isDestroyed}set isDestroyed(e){this._isDestroyed=e,this.updateStatus()}get isEnvReady(){return this._isEnvReady}set isEnvReady(e){this._isEnvReady=e,this.updateStatus()}get sessionStatus(){return this._sessionStatus}set sessionStatus(e){this._sessionStatus=e,this.updateStatus()}get status(){return this._status}set status(e){var n,t;this._status=e,null===(t=(n=this.opts).onStatusChange)||void 0===t||t.call(n,e)}runCmd(n){this.status!==e.DevbookStatus.Disconnected&&this.context.executeCommand({templateID:this.opts.env,executionID:this.executionID,command:n})}runCode(e){const n=o[this.opts.env].toCommand(e);this.runCmd(n)}destroy(){this.context.destroy(),this.isDestroyed=!0}updateStatus(){if(this.isDestroyed)return void(this.status!==e.DevbookStatus.Disconnected&&(this.status=e.DevbookStatus.Disconnected));let n;switch(this.sessionStatus){case m.Disconnected:n=e.DevbookStatus.Disconnected;break;case m.Connecting:n=e.DevbookStatus.Connecting;break;case m.Connected:if(!this.isEnvReady){n=e.DevbookStatus.Connecting;break}n=e.DevbookStatus.Connected}this.status=n}}e.Devbook=w,e.useDevbook=function({env:t,debug:s}){const[i,o]=n.useState(),[r,a]=n.useState(e.DevbookStatus.Disconnected),[l,c]=n.useState([]),[d,h]=n.useState([]),u=n.useCallback((e=>{i&&(h([]),c([]),i.runCmd(e))}),[i]),g=n.useCallback((e=>{i&&(h([]),c([]),i.runCode(e))}),[i]);return n.useEffect((function(){const e=new w({debug:s,env:t,onStatusChange(e){a(e)},onStderr(e){c((n=>[...n,e]))},onStdout(e){h((n=>[...n,e]))}});return h([]),c([]),o(e),()=>{e.destroy()}}),[t,s]),{stderr:l,stdout:d,runCmd:u,runCode:g,status:r}},Object.defineProperty(e,"__esModule",{value:!0})}));
***************************************************************************** */function s(e,n,t,s){return new(t||(t=Promise))((function(i,o){function r(e){try{c(s.next(e))}catch(e){o(e)}}function a(e){try{c(s.throw(e))}catch(e){o(e)}}function c(e){var n;e.done?i(e.value):(n=e.value,n instanceof t?n:new t((function(e){e(n)}))).then(r,a)}c((s=s.apply(e,n||[])).next())}))}function i(e){return new Promise((n=>setTimeout(n,e)))}var o,r,a;!function(e){e.Error="Runner.Error"}(o||(o={})),function(e){e.Start="RunningEnvironment.Start",e.StartAck="RunningEnvironment.StartAck",e.Eval="RunningEnvironment.Eval",e.FSEventCreate="RunningEnvironment.FSEventCreate",e.FSEventRemove="RunningEnvironment.FSEventRemove",e.FSEventWrite="RunningEnvironment.FSEventWrite",e.CreateDir="RunningEnvironment.CreateDir",e.ListDir="RunningEnvironment.ListDir",e.WriteFile="RunningEnvironment.WriteFile",e.GetFile="RunningEnvironment.GetFile",e.RemoveFile="RunningEnvironment.RemoveFile",e.DirContent="RunningEnvironment.DirContent",e.FileContent="RunningEnvironment.FileContent",e.Stdout="RunningEnvironment.Stdout",e.Stderr="RunningEnvironment.Stderr",e.ExecCmd="RunningEnvironment.ExecCmd",e.KillCmd="RunningEnvironment.KillCmd",e.ListRunningCmds="RunningEnvironment.ListRunningCmds",e.CmdOut="RunningEnvironment.CmdOut",e.CmdExit="RunningEnvironment.CmdExit",e.RunningCmds="RunningEnvironment.RunningCmds",e.RunCode="RunningEnvironment.Run"}(r||(r={})),function(e){e.Error="CodeCell.Error"}(a||(a={}));const c={Runner:o,RunningEnvironment:r,CodeCell:a},l="orchestrator.usedevbook.com",h="dbk_sdk_session_id",d=3e3;e.Env=void 0,(e.Env||(e.Env={})).NodeJS="nodejs-v16";const u={"nodejs-v16":{id:"nodejs-v16",fileExtension:".js",image:"us-central1-docker.pkg.dev/devbookhq/devbook-runner-templates/nodejs-v16:latest",root_dir:"/home/runner",code_cells_dir:"/home/runner/src",toCommand:e=>`node "${e}"`}};class g{constructor(){this.url=`wss://${l}`,this.logger=new t("WebSocketConnection"),this.handlers=[]}get state(){var e;return null===(e=this.client)||void 0===e?void 0:e.readyState}get isClosed(){if(void 0!==this.client)return this.client.readyState===this.client.CLOSED}get isClosing(){if(void 0!==this.client)return this.client.readyState===this.client.CLOSING}get isOpen(){if(void 0!==this.client)return this.client.readyState===this.client.OPEN}get isConnecting(){if(void 0!==this.client)return this.client.readyState===this.client.CONNECTING}subscribeHandler(e){return this.handlers.push(e),()=>{this.handlers=this.handlers.filter((n=>n!==e))}}connect(e){(!this.client||this.client.readyState!==this.client.CONNECTING&&this.client.readyState!==this.client.OPEN)&&(e||this.sessionID?(e?(this.logger.log(`Will try to connect to session "${e}"`),this.sessionID=e):!e&&this.sessionID&&this.logger.log(`Will try to connect to previous session "${this.sessionID}"`),this.client=new WebSocket(`${this.url}/session/ws/${this.sessionID}`),this.client.onopen=()=>this.handleOpen(),this.client.onmessage=e=>{this.logger.log("Received (raw)",{msg:e}),this.handleMessage(e)},this.client.onerror=e=>this.handleError(e),this.client.onclose=e=>this.handleClose(e)):this.logger.error("Cannot connect, no session ID passed to the function and no session ID saved from the previous session"))}send(e){this.client&&this.client.readyState===this.client.OPEN?(this.logger.log("Send",e),this._send(e)):this.logger.warn("Trying to send a message while not being in the `OPEN` state or without established connection, message will be discarded",e)}close(){var e;this.logger.log("Closing connection"),null===(e=this.client)||void 0===e||e.close(1e3)}handleOpen(){var e;this.logger.log("Connection opened",{readyState:null===(e=this.client)||void 0===e?void 0:e.readyState}),this.handlers.forEach((e=>e.onOpen()))}_send(e){var n,t;null===(n=this.client)||void 0===n||n.send((t=e,JSON.stringify(t,(()=>{const e=new WeakSet;return(n,t)=>{if("object"==typeof t&&null!==t){if(e.has(t))return;e.add(t)}return t}})(),2)))}handleClose(e){return s(this,void 0,void 0,(function*(){this.logger.log("Connection closed",e),this.handlers.forEach((e=>e.onClose())),this.logger.log("Will try to reconnect in 3s"),yield i(3e3),this.connect()}))}handleError(e){var n;this.logger.error("Connection error",e),null===(n=this.client)||void 0===n||n.close()}handleMessage(e){if(!e.data)return void this.logger.error("Message has empty data field",e);const n=JSON.parse(e.data);if(!n.type)return void this.logger.error("Message has no type",n);const t=n;Object.values(c.RunningEnvironment).includes(t.type)||Object.values(c.Runner).includes(t.type)||Object.values(c.CodeCell).includes(t.type)?t.type!==c.Runner.Error?(this.logger.log("Received (parsed)",t),this.handlers.forEach((e=>e.onMessage(t)))):this.logger.error("Runner error",t):this.logger.error('Message "type" field has unexpected value',t)}}var v,m;!function(e){e.Ok="Ok",e.Terminated="Terminated"}(v||(v={}));class p{constructor(e,n=new Date){this.id=e,this.lastPing=n,this.logger=new t("RunnerSession"),this.url=`https://${l}`}ping(){return s(this,void 0,void 0,(function*(){this.logger.log(`Pinging session "${this.id}"`);const e=JSON.stringify({sessionID:this.id});try{const n=yield fetch(`${this.url}/session/ping`,{method:"POST",headers:{"Content-Type":"application/json"},body:e}),t=yield n.json();if(!n.ok)throw this.logger.error(n.headers,t),new Error("Non-OK response when trying to ping active Runner session");if(t.status===v.Terminated)throw new Error(`[keepAlive]: Session '${this.id}' is terminated`);this.lastPing=new Date}catch(e){throw this.logger.error(e),new Error("Failed to ping active Runner session")}}))}}!function(e){e.Connected="Connected",e.Connecting="Connecting",e.Disconnected="Disconnected"}(m||(m={}));class f{constructor(e){this.conn=e,this.logger=new t("SessionManager"),this.url=`https://${l}`,this.isGettingSessionActive=!1,this.status=m.Disconnected,this.logger.log("Initialize"),this.getSession()}get cachedSessionID(){return sessionStorage.getItem(h)}set cachedSessionID(e){null===e?(this.logger.log("Cleared last sessionID"),sessionStorage.removeItem(h)):(this.logger.log(`Saved sessionID "${e}" as last sessionID`),sessionStorage.setItem(h,e))}reset(){this.logger.log("Reset"),this.status=m.Disconnected,this.cachedSessionID=null,this.conn.close(),this.session=void 0}getSession(){var e;return s(this,void 0,void 0,(function*(){if(!this.isGettingSessionActive)for(this.isGettingSessionActive=!0;;){this.status=m.Connecting;try{const n=this.cachedSessionID?`${this.url}/session/${this.cachedSessionID}`:`${this.url}/session`;this.cachedSessionID?this.logger.log(`Restoring old Runner session "${this.cachedSessionID}"`):this.logger.log("Acquiring new Runner session");const t=yield fetch(n),s=yield t.json();if(!t.ok){this.logger.error("Non-OK response when trying to ping active Runner session. Will try again in 3s",t.headers,s),yield i(d);continue}for(this.session=new p(s.sessionID),this.logger.log(`Acquired session "${this.session.id}"`),this.cachedSessionID=this.session.id,this.status=m.Connected,this.conn.connect(this.session.id),this.logger.log(`Started pinging session "${this.session.id}"`);this.session;)try{yield this.session.ping(),yield i(5e3)}catch(e){this.logger.error(`Failed to ping session "${this.session.id}"`,e);break}this.logger.log(`Stopped pinging session "${null===(e=this.session)||void 0===e?void 0:e.id}"`),this.session=void 0,this.status=m.Disconnected,this.conn.close()}catch(e){this.logger.error("Failed to acquire Runner session. Will try again in 3s",e),yield i(d)}}}))}}function D(e,n){for(var t=0,s=e.length-1;s>=0;s--){var i=e[s];"."===i?e.splice(s,1):".."===i?(e.splice(s,1),t++):t&&(e.splice(s,1),t--)}if(n)for(;t--;t)e.unshift("..");return e}var C=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/,S=function(e){return C.exec(e).slice(1)};function b(){for(var e="",n=!1,t=arguments.length-1;t>=-1&&!n;t--){var s=t>=0?arguments[t]:"/";if("string"!=typeof s)throw new TypeError("Arguments to path.resolve must be strings");s&&(e=s+"/"+e,n="/"===s.charAt(0))}return(n?"/":"")+(e=D(R(e.split("/"),(function(e){return!!e})),!n).join("/"))||"."}function E(e){var n=y(e),t="/"===w(e,-1);return(e=D(R(e.split("/"),(function(e){return!!e})),!n).join("/"))||n||(e="."),e&&t&&(e+="/"),(n?"/":"")+e}function y(e){return"/"===e.charAt(0)}var I={extname:function(e){return S(e)[3]},basename:function(e,n){var t=S(e)[2];return n&&t.substr(-1*n.length)===n&&(t=t.substr(0,t.length-n.length)),t},dirname:function(e){var n=S(e),t=n[0],s=n[1];return t||s?(s&&(s=s.substr(0,s.length-1)),t+s):"."},sep:"/",delimiter:":",relative:function(e,n){function t(e){for(var n=0;n<e.length&&""===e[n];n++);for(var t=e.length-1;t>=0&&""===e[t];t--);return n>t?[]:e.slice(n,t-n+1)}e=b(e).substr(1),n=b(n).substr(1);for(var s=t(e.split("/")),i=t(n.split("/")),o=Math.min(s.length,i.length),r=o,a=0;a<o;a++)if(s[a]!==i[a]){r=a;break}var c=[];for(a=r;a<s.length;a++)c.push("..");return(c=c.concat(i.slice(r))).join("/")},join:function(){var e=Array.prototype.slice.call(arguments,0);return E(R(e,(function(e,n){if("string"!=typeof e)throw new TypeError("Arguments to path.join must be strings");return e})).join("/"))},isAbsolute:y,normalize:E,resolve:b};function R(e,n){if(e.filter)return e.filter(n);for(var t=[],s=0;s<e.length;s++)n(e[s],s,e)&&t.push(e[s]);return t}var x,w="b"==="ab".substr(-1)?function(e,n,t){return e.substr(n,t)}:function(e,n,t){return n<0&&(n=e.length+n),e.substr(n,t)};function k(e){return function(e){const n=Array.from(e).reduce(((e,n)=>0|31*e+n.charCodeAt(0)),0);return("0000000"+(n>>>0).toString(16)).slice(-8)}(e)}class _{constructor(e,n){this.contextID=e,this.templateID=n,this.isReady=!1,this.id=`${e}_${k(n)}`,this.template=u[this.templateID]}}function O(e,{environmentID:n,template:t}){const s={type:c.RunningEnvironment.Start,payload:{environmentID:n,template:t}};e.send(s)}function $(e,{environmentID:n,executionID:t,command:s}){const i={type:c.RunningEnvironment.ExecCmd,payload:{environmentID:n,executionID:t,command:s}};e.send(i)}class j{constructor(e){this.opts=e,this.fsWriteSubscribers=[],this.envs=[],this.logger=new t("EvaluationContext",e.debug),this.unsubscribeConnHandler=this.opts.conn.subscribeHandler({onOpen:this.handleConnectionOpen.bind(this),onMessage:this.handleConnectionMessage.bind(this),onClose:this.handleConnectionClose.bind(this)}),this.opts.conn.isOpen&&this.handleConnectionOpen(),this.opts.conn.isClosed&&this.handleConnectionClose()}get contextID(){return this.opts.contextID}restart(){return this.logger.log("Restart",this.opts.conn.sessionID),this.envs.forEach((e=>{e.isReady=!1,O(this.opts.conn,{environmentID:e.id,template:e.template})}))}destroy(){this.logger.log("Destroy"),this.unsubscribeConnHandler(),this.envs=[],this.fsWriteSubscribers=[]}executeCode({templateID:e,executionID:n,code:t}){return s(this,void 0,void 0,(function*(){this.logger.log("Execute code",{templateID:e,executionID:n});const s=this.envs.find((n=>n.templateID===e));if(!s)return void this.logger.error("Environment not found",{templateID:e,executionID:n});if(!s.isReady)return void this.logger.error("Environment is not ready",{templateID:e,executionID:n});const i=u[e].fileExtension,o=`${n}${i}`,r=I.join("/src",o);let a;const l=new Promise(((e,n)=>{a=e,setTimeout((()=>{n()}),1e4)})),h=e=>{e.path.endsWith(r)&&a()};this.subscribeFSWrite(h),function(e,{environmentID:n,path:t,content:s}){const i={type:c.RunningEnvironment.WriteFile,payload:{environmentID:n,path:t,content:s}};e.send(i)}(this.opts.conn,{environmentID:s.id,path:r,content:t});try{yield l}catch(e){return void this.logger.error(`File ${r} not written to VM`)}finally{this.unsubscribeFSWrite(h)}const d=I.join(u[e].root_dir,r),g=u[e].toCommand(d);$(this.opts.conn,{environmentID:s.id,executionID:n,command:g})}))}executeCommand({templateID:e,executionID:n,command:t}){this.logger.log("Execute shell command",{templateID:e,executionID:n,command:t});const s=this.envs.find((n=>n.templateID===e));s?s.isReady?$(this.opts.conn,{environmentID:s.id,executionID:n,command:t}):this.logger.error("Environment is not ready",{templateID:e,executionID:n,command:t}):this.logger.error("Environment not found",{templateID:e,executionID:n,command:t})}createRunningEnvironment({templateID:e}){var n,t;this.logger.log("Creating running environment",{templateID:e});if(this.envs.find((n=>n.templateID===e)))return;const s=new _(this.contextID,e);this.envs=[...this.envs,s],O(this.opts.conn,{environmentID:s.id,template:s.template}),null===(t=(n=this.opts).onEnvChange)||void 0===t||t.call(n,s)}subscribeFSWrite(e){this.fsWriteSubscribers.push(e)}unsubscribeFSWrite(e){this.fsWriteSubscribers=this.fsWriteSubscribers.filter((n=>n!==e))}handleConnectionOpen(){var e,n;this.restart(),null===(n=(e=this.opts).onSessionChange)||void 0===n||n.call(e,{status:m.Connected})}handleConnectionClose(){var e,n;null===(n=(e=this.opts).onSessionChange)||void 0===n||n.call(e,{status:m.Connecting})}handleConnectionMessage(e){switch(this.logger.log("Handling message from remote Runner",{message:e}),e.type){case c.RunningEnvironment.StartAck:{const n=e;this.vmenv_handleStartAck(n.payload);break}case c.RunningEnvironment.CmdOut:{const n=e;this.vmenv_handleCmdOut(n.payload);break}case c.RunningEnvironment.CmdExit:{const n=e;this.vmenv_handleCmdExit(n.payload);break}case c.RunningEnvironment.FSEventWrite:{const n=e;this.vmenv_handleFSEventWrite(n.payload);break}default:this.logger.warn("Unknown message type",{message:e})}}vmenv_handleCmdExit(e){var n,t;void 0!==e.error&&(null===(t=(n=this.opts).onCmdOut)||void 0===t||t.call(n,{environmentID:e.environmentID,executionID:e.executionID,stderr:e.error}))}vmenv_handleFSEventWrite(e){this.logger.log('[vmenv] Handling "FSEventWrite"',e);this.envs.find((n=>n.id===e.environmentID))?this.fsWriteSubscribers.forEach((n=>n(e))):this.logger.warn("Environment not found",{payload:e})}vmenv_handleStartAck(e){var n,t;this.logger.log('[vmenv] Handling "StartAck"',{payload:e});const s=this.envs.find((n=>n.id===e.environmentID));s?(s.isReady=!0,null===(t=(n=this.opts).onEnvChange)||void 0===t||t.call(n,s)):this.logger.warn("Environment not found",{payload:e})}vmenv_handleCmdOut(e){var n,t;this.logger.log('[vmenv] Handling "CmdOut"',e),null===(t=(n=this.opts).onCmdOut)||void 0===t||t.call(n,e)}}class W{constructor(){this.logger=new t("Runner"),this.conn=new g,this.sessManager=new f(this.conn)}static get obj(){return W._obj||(W._obj=new W)}get session(){return this.sessManager.session}get status(){return this.sessManager.status}reset(){this.logger.log("Reset"),this.sessManager.reset()}createContext(e){return new j(Object.assign(Object.assign({},e),{conn:this.conn}))}__debug__loadNewSession(){this.logger.log("__debug__loadNewSession"),this.sessManager.reset()}}e.DevbookStatus=void 0,(x=e.DevbookStatus||(e.DevbookStatus={}))[x.Disconnected=0]="Disconnected",x[x.Connecting=1]="Connecting",x[x.Connected=2]="Connected";class F{constructor(n){this.opts=n,this._isDestroyed=!1,this._isEnvReady=!1,this._sessionStatus=m.Disconnected,this._status=e.DevbookStatus.Disconnected;const t="default";this.contextID=t;this.executionID="def";const s=e=>this.isEnvReady=e,i=e=>this.sessionStatus=e;this.context=W.obj.createContext({debug:n.debug,contextID:t,onEnvChange(e){s(e.isReady)},onSessionChange({status:e}){i(e)},onCmdOut(e){var t,s;"def"===e.executionID&&(void 0!==e.stdout&&(null===(t=n.onStdout)||void 0===t||t.call(n,e.stdout)),void 0!==e.stderr&&(null===(s=n.onStderr)||void 0===s||s.call(n,e.stderr)))}}),this.context.createRunningEnvironment({templateID:n.env})}get isDestroyed(){return this._isDestroyed}set isDestroyed(e){this._isDestroyed=e,this.updateStatus()}get isEnvReady(){return this._isEnvReady}set isEnvReady(e){this._isEnvReady=e,this.updateStatus()}get sessionStatus(){return this._sessionStatus}set sessionStatus(e){this._sessionStatus=e,this.updateStatus()}get status(){return this._status}set status(e){var n,t;this._status=e,null===(t=(n=this.opts).onStatusChange)||void 0===t||t.call(n,e)}runCmd(n){this.status!==e.DevbookStatus.Disconnected&&this.context.executeCommand({templateID:this.opts.env,executionID:this.executionID,command:n})}runCode(n){this.status!==e.DevbookStatus.Disconnected&&this.context.executeCode({templateID:this.opts.env,executionID:this.executionID,code:n})}destroy(){this.context.destroy(),this.isDestroyed=!0}updateStatus(){if(this.isDestroyed)return void(this.status!==e.DevbookStatus.Disconnected&&(this.status=e.DevbookStatus.Disconnected));let n;switch(this.sessionStatus){case m.Disconnected:n=e.DevbookStatus.Disconnected;break;case m.Connecting:n=e.DevbookStatus.Connecting;break;case m.Connected:if(!this.isEnvReady){n=e.DevbookStatus.Connecting;break}n=e.DevbookStatus.Connected}this.status=n}}e.Devbook=F,e.useDevbook=function({env:t,debug:s}){const[i,o]=n.useState(),[r,a]=n.useState(e.DevbookStatus.Disconnected),[c,l]=n.useState([]),[h,d]=n.useState([]),u=n.useCallback((e=>{i&&(d([]),l([]),i.runCmd(e))}),[i]),g=n.useCallback((e=>{i&&(d([]),l([]),i.runCode(e))}),[i]);return n.useEffect((function(){const e=new F({debug:s,env:t,onStatusChange(e){a(e)},onStderr(e){l((n=>[...n,e]))},onStdout(e){d((n=>[...n,e]))}});return d([]),l([]),o(e),()=>{e.destroy()}}),[t,s]),{stderr:c,stdout:h,runCmd:u,runCode:g,status:r}},Object.defineProperty(e,"__esModule",{value:!0})}));
//# sourceMappingURL=index.js.map
{
"name": "@devbookhq/sdk",
"version": "0.1.2",
"version": "0.1.3",
"description": "Devbook allows visitors of your docs to interact with and execute any code snippet or shell command in a private VM",

@@ -26,9 +26,4 @@ "homepage": "https://usedevbook.com",

"devDependencies": {
"@babel/core": "^7.16.7",
"@babel/preset-react": "^7.16.7",
"@rollup/plugin-alias": "^3.1.9",
"@rollup/plugin-babel": "^5.3.0",
"@rollup/plugin-commonjs": "^21.0.1",
"@rollup/plugin-node-resolve": "^13.1.3",
"@types/node": "^17.0.9",
"@types/node": "^17.0.10",
"@types/react": "^17.0.38",

@@ -38,2 +33,3 @@ "@types/react-dom": "^17.0.11",

"rollup-plugin-auto-external": "^2.0.0",
"rollup-plugin-polyfill-node": "^0.8.0",
"rollup-plugin-terser": "^7.0.2",

@@ -60,2 +56,2 @@ "rollup-plugin-typescript2": "^0.31.1",

]
}
}

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

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