All Projects → replit → crosis

replit / crosis

Licence: MIT license
A JavaScript client that speaks Replit's container protocol

Programming Languages

typescript
32286 projects
javascript
184084 projects - #8 most used programming language
HTML
75241 projects

Projects that are alternatives of or similar to crosis

Lgo
Interactive Go programming with Jupyter
Stars: ✭ 2,225 (+2517.65%)
Mutual labels:  repl
Lfortran
Official mirror of https://gitlab.com/lfortran/lfortran. Please submit pull requests (PR) there. Any PR sent here will be closed automatically.
Stars: ✭ 220 (+158.82%)
Mutual labels:  repl
swiftreplmadness
Example of using your own packages in the Swift REPL
Stars: ✭ 18 (-78.82%)
Mutual labels:  repl
Blazorrepl
Write, compile, execute and share Blazor components entirely in the browser
Stars: ✭ 196 (+130.59%)
Mutual labels:  repl
Vsh
vsh - HashiCorp Vault interactive shell and cli tool
Stars: ✭ 209 (+145.88%)
Mutual labels:  repl
Mond
A scripting language for .NET Core
Stars: ✭ 237 (+178.82%)
Mutual labels:  repl
Fridayuserbot
A Pluggable And Powerful Telegram Manager Bot
Stars: ✭ 183 (+115.29%)
Mutual labels:  repl
elasticsearch-cli
Provides a REPL console-like interface to interact with Elasticsearch
Stars: ✭ 15 (-82.35%)
Mutual labels:  repl
Unrepl
A common ground for better Clojure REPLs
Stars: ✭ 222 (+161.18%)
Mutual labels:  repl
Ipython
Official repository for IPython itself. Other repos in the IPython organization contain things like the website, documentation builds, etc.
Stars: ✭ 15,107 (+17672.94%)
Mutual labels:  repl
Gluon
A static, type inferred and embeddable language written in Rust.
Stars: ✭ 2,457 (+2790.59%)
Mutual labels:  repl
Codi.vim
📔 The interactive scratchpad for hackers.
Stars: ✭ 2,464 (+2798.82%)
Mutual labels:  repl
Tslab
Interactive JavaScript and TypeScript programming with Jupyter
Stars: ✭ 240 (+182.35%)
Mutual labels:  repl
Dynaml
Scala Library/REPL for Machine Learning Research
Stars: ✭ 195 (+129.41%)
Mutual labels:  repl
sliver
REPL for SilverStripe, powered by Psysh. Interactively debug and tinker with a sliver of your code.
Stars: ✭ 17 (-80%)
Mutual labels:  repl
Charly
🐈 The Charly Programming Language | Written by @KCreate
Stars: ✭ 185 (+117.65%)
Mutual labels:  repl
Box
A mruby-based Builder for Docker Images
Stars: ✭ 236 (+177.65%)
Mutual labels:  repl
fundot
The Fundot programming language.
Stars: ✭ 15 (-82.35%)
Mutual labels:  repl
dotnet-repl
A polyglot REPL built on .NET Interactive
Stars: ✭ 522 (+514.12%)
Mutual labels:  repl
Go Pry
An interactive REPL for Go that allows you to drop into your code at any point.
Stars: ✭ 2,747 (+3131.76%)
Mutual labels:  repl

Installation

yarn add @replit/crosis @replit/protocol

Crosis relies on the @replit/protocol package as a peer dependency. https://github.com/replit/protocol

Prerequisites

You should probably familiarize yourself with the protocol before trying to use it. Crosis is just a client that helps you connect and communicate with the container using the protocol.

Read about the protocol here https://crosis-doc.util.repl.co/

Usage and concepts

The central concept is a "channel" that you can send commands to and receive commands from. Communicating with channels requires a network connection. The goal of this client is to provide an API to manage the connection (including disconnects and reconnects), opening channels, and a way to send a receive messages/commands on channels. How you handle this is up to you and depends on the desired UX. In some cases you'll want to disable UI to prevent any new messages from being sent when offline and then re-enable once connected again. In other cases you might want to give the user the illusion that they are connected and queue messages locally while disconnected and send them once reconnected.

Here is an example usage, for more details on usage please refer to the API docs at https://crosisdoc.util.repl.co/

import { Client } from '@replit/crosis';

const client = new Client<{ user: { name: string }; repl: { id: string } }>();

const repl = { id: 'someuuid' };

async function fetchConnectionMetadata(
  signal: AbortSignal,
): Promise<FetchConnectionMetadataResult> {
  let res: Response;
  try {
    res = await fetch(CONNECTION_METADATA_URL + repl.id, { signal });
  } catch (error) {
    if (error.name === 'AbortError') {
      return {
        error: FetchConnectionMetadataError.Aborted,
      };
    }

    throw error;
  }

  if (!res.ok) {
    if (res.status > 500) {
      // Network or server error, try again
      return {
        error: FetchConnectionMetadataError.Retriable,
      };
    }

    const errorText = await res.text();
    throw new Error(errorText || res.statusText);
  }

  const connectionMetadata = await res.json();

  return {
    token: connectionMetadata.token,
    gurl: connectionMetadata.gurl,
    conmanURL: connectionMetadata.conmanURL,
    error: null,
  };
}

const user = { name: 'tim' };

const context = { user, repl };

client.open({ context, fetchConnectionMetadata }, function onOpen({ channel, context }) {
  if (!channel) {
    // Closed before ever connecting. Due to `client.close` being called
    // or an unrecoverable, that can be handled by setting `client.setUnrecoverableError`
    return;
  }

  //  The client is now connected (or reconnected in the event that it encountered an unexpected disconnect)
  // `channel` here is channel0 (more info at https://crosis-doc.util.repl.co/protov2)
  // - send commands using `channel.send`
  // - listen for commands using `channel.onCommand(cmd => ...)`

  return function cleanup({ willReconnect }) {
    // The client was closed and might reconnect if it was closed unexpectedly
  };
});

// See docs for exec service here https://crosis-doc.util.repl.co/services#exec
const closeChannel = client.openChannel({ service: 'exec' }, function open({ channel, context }) {
  if (!channel) {
    // Closed before ever connecting. Due to `client.close` being called, `closeChannel` being called
    // or an unrecoverable, that can be handled by setting `client.setUnrecoverableErr
    return;
  }

  channel.onCommand((cmd) => {
    if (cmd.output) {
      terminal.write(cmd.output);
    }
  });

  const intervalId = setInterval(() => {
    channel.send({
      exec: { args: ['echo', 'hello', context.user.name] },
      blocking: true,
    });
  }, 100);

  return function cleanup({ willReconnect }) {
    clearInterval(intervalId);
  };
});

Developing

To run tests run

USER_KEY_ID=XXXX USER_PRIVATE_KEY=XXXX yarn test

To interact with a connected client in the browser run

USER_KEY_ID=XXXX USER_PRIVATE_KEY=XXXX yarn debug

You can then access the client from the console an send messages like:

window.client.send({ exec: { args: ['kill', '1'] } });

Releasing

To release, just run USER_KEY_ID=XXXX USER_PRIVATE_KEY=XXXX yarn version, it will prompt you for a version, then it will push to github and release to npm.

To update documentation, go to https://crosisdoc.util.repl.co/__repl and run . ./updatedocs.sh

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].