Skip to content

Commit

Permalink
refactor(*): feedback review from @Mouvedia
Browse files Browse the repository at this point in the history
  • Loading branch information
topheman committed Mar 6, 2024
1 parent 86726e9 commit 8a1c0cd
Show file tree
Hide file tree
Showing 12 changed files with 50 additions and 32 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# rust
/target
render.out

# nodejs
node_modules
dist
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ To run:

## JavaScript

The [`snakepipe render-browser`](./README.md#-you-can-mirror-your-playing-terminal-into-another-one-through-http) command launches a rust http server that serves some JavaScript code that connects to server-sent-events and renders the game inside the browser.
The [`snakepipe render-browser`](./README.md#-you-can-mirror-your-playing-terminal-into-another-one-through-http) command launches a rust http server that serves some JavaScript code that connects to server-sent events and renders the game inside the browser.

The source code for the renderers is available at [`static/renderers`](static/renderers).

Expand Down
7 changes: 7 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Copyright (C) 2024 Christophe Rosset <[email protected]>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ This one follows the [unix philosophy](https://en.wikipedia.org/wiki/Unix_philos
- `snakepipe gamestate` accepts user inputs, calculates the state of the game and writes it to `stdout`
- `snakepipe render` reads the state of the game from `stdin` and renders it on the terminal
- `snakepipe throttle` reads a pre-recorded game from `stdin` and writes to `stdout` each tick so that `snakepipe render` can pick it up
- `snakepipe render-browser` spawns a server and sends `stdin` via server-sent-events to a JavaScript renderer in your browser
- `snakepipe stream-sse` connects to the server spawned by `render-browser` and streams server-sent-events back to the terminal
- `snakepipe render-browser` spawns a server and sends `stdin` via server-sent events to a JavaScript renderer in your browser
- `snakepipe stream-sse` connects to the server spawned by `render-browser` and streams server-sent events back to the terminal
- `snakepipe pipeline <command>` prints out the most common pipelines (combinations of commands), so that you could directly `pbcopy`/paste them

That way:
Expand All @@ -24,7 +24,7 @@ That way:

## Motivation

I've already done [a few rust projects](http://labs.topheman.com) (with WebAssembly or bevy), however, I wanted something that needs to deal directly with:
I've already done [a few rust projects](http://labs.topheman.com) (with WebAssembly or [bevy](https://github.com/topheman/bevy-rust-wasm-experiments)), however, I wanted something that needs to deal directly with:

- I/O
- parsing
Expand Down Expand Up @@ -86,7 +86,7 @@ snakepipe gamestate|tee /tmp/snakepipe.sock|snakepipe render
snakepipe gamestate|snakepipe render-browser|snakepipe render
```

Then open [http://localhost:8080](http://localhost:8080). You'll be able to switch between renderers in your browser as you are playing in your terminal (thanks to server-sent-events).
Then open [http://localhost:8080](http://localhost:8080). You'll be able to switch between renderers in your browser as you are playing in your terminal (thanks to server-sent events).

### 🖼 You can mirror your playing terminal into another one, through http

Expand All @@ -95,14 +95,14 @@ Open two terminals:
```sh
# main terminal:
# - accepts user inputs
# - spawns an http server that streams stdin to server-sent-events
# - spawns an http server that streams stdin to server-sent events
# - renders the game to the terminal so you can play
snakepipe gamestate|snakepipe render-browser|snakepipe render
```

```sh
# mirroring terminal (not necessary the same device, only need to be on the same network):
# - connects to the http server and streams server-sent-events to sdout
# - connects to the http server and streams server-sent events to sdout
# - render the gamestate retrieved from the server
snakepipe stream-sse|snakepipe render
```
Expand All @@ -124,8 +124,8 @@ Commands:
gamestate Accepts user inputs (arrow keys to control the snake) and outputs the state of the game to stdout
render Reads gamestate from stdin and renders the game on your terminal
throttle Reads stdin line by line and outputs each line on stdout each `frame_duration` ms (usefull for replaying a file)
render-browser Let's you render the game in your browser at http://localhost:8080 by spawning a server and sending stdin via server-sent-events to a JavaScript renderer
stream-sse Connects to the server spawned by `render-browser` and streams server-sent-events back to the terminal
render-browser Let's you render the game in your browser at http://localhost:8080 by spawning a server and sending stdin via server-sent events to a JavaScript renderer
stream-sse Connects to the server spawned by `render-browser` and streams server-sent events back to the terminal
help Print this message or the help of the given subcommand(s)

Options:
Expand Down Expand Up @@ -174,7 +174,7 @@ Options:
<details>
<summary><code>snakepipe render-browser --help</code></summary>
<pre>
Let's you render the game in your browser at http://localhost:8080 by spawning a server and sending stdin via server-sent-events to a JavaScript renderer
Let's you render the game in your browser at http://localhost:8080 by spawning a server and sending stdin via server-sent events to a JavaScript renderer

Usage: snakepipe render-browser [OPTIONS]

Expand All @@ -186,7 +186,7 @@ Options:
<details>
<summary><code>snakepipe stream-sse --help</code></summary>
<pre>
Connects to the server spawned by `render-browser` and streams server-sent-events back to the terminal
Connects to the server spawned by `render-browser` and streams server-sent events back to the terminal

Usage: snakepipe stream-sse [OPTIONS]

Expand Down
2 changes: 1 addition & 1 deletion RECORDING_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ snakepipe gamestate|snakepipe render
---

```sh
# Record a party by saving the output of gamestate command to a file with the built-in tee utility
# Record a party by saving the output of the gamestate command to a file with the built-in tee utility

snakepipe gamestate|tee /tmp/snake-output|snakepipe render
```
Expand Down
27 changes: 17 additions & 10 deletions node-helpers/dev-server-sse/index.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,32 @@
import path from 'node:path';
import fs from 'node:fs/promises';
import url from 'url';
import { setTimeout } from 'node:timers/promises';
import url from 'node:url';

import localIpUrl from 'local-ip-url';
import { parseGameStateFromAsyncIterator, InitOptions } from 'snakepipe';

import { makeServer } from './server.js'


/**
* `__dirname` doesn't exist in esm, you need to create it.
*
* We could improve the code bellow with just `import.meta.dirname` - it needs at least node 20.11.
* For the moment keeping retrocompatibility with all node 20 versions.
*
* Source: https://nodejs.org/docs/v20.11.0/api/esm.html#importmetadirname
*/
const __dirname = url.fileURLToPath(new URL('.', import.meta.url)); // __dirname for esm

const ExitCodeUsageError = 64; // The command was used incorrectly, e.g., with the wrong number of arguments, a bad flag, a bad syntax in a parameter, etc.

if (process.argv.length < 3) {
console.log("You must pass the path of the file containing the recording of a game.");
process.exit(64);
process.exit(ExitCodeUsageError);
}
if (process.argv.length > 3) {
console.log("Too much arguments passed");
process.exit(64);
console.log("Too many arguments passed");
process.exit(ExitCodeUsageError);
}

const [filePathOfGameRecording] = process.argv.slice(2, 3);
Expand All @@ -30,17 +41,13 @@ if (path.isAbsolute(filePathOfGameRecording)) {

main(resolvedFilePathOfGameRecording);

function timeout(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
}

async function* infiniteAsyncGeneratorFromArrayString(input: Array<string>, delay = 120) {
let currentIndex = 0;
yield input[currentIndex];
while (true) {
currentIndex++;
if (input[currentIndex]?.trim()) {
await timeout(120);
await setTimeout(delay);
yield input[currentIndex]
}
else {
Expand Down
2 changes: 1 addition & 1 deletion node-helpers/dev-server-sse/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export function makeServer(input: Input, staticFolder: string) {
res.sse({ data: JSON.stringify(line) });
}
req.raw.on('close', () => {
gameEvents.off("line", listener); // if used in production with eavy traffic, consider augment `emitter.setMaxListeners()` (currently up to 11 clients in parallel)
gameEvents.off("line", listener); // if used in production with eavy traffic, consider increasing `emitter.setMaxListeners()` (currently up to 11 clients in parallel)
res.sseContext.source.end();
})
res.sse({ data: "connected" });
Expand Down
4 changes: 2 additions & 2 deletions node-helpers/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "node-helpers",
"version": "0.1.0",
"description": "Set of tools for better development of JavaScript part.",
"description": "Set of tools for better development of JavaScript parts.",
"type": "module",
"scripts": {
"build": "tsc",
Expand All @@ -19,6 +19,6 @@
"@fastify/static": "^7.0.1",
"fastify": "^4.26.1",
"fastify-sse-v2": "^3.1.2",
"snakepipe": "^0.1.3"
"snakepipe": "latest"
}
}
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "snake-pipe-rust",
"version": "0.1.0",
"private": true,
"description": "You only need this part for better experience with js development, not mandadtory.",
"description": "You only need this part for a better experience with js development, not mandadtory.",
"scripts": {
"build": "npm run --workspace=node-helpers build",
"setup": "npm run --workspace=node-helpers setup",
Expand Down
4 changes: 2 additions & 2 deletions src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ mod tests {
}

#[test]
fn should_have_as_many_versions_as_it_exist() {
fn should_extract_all_existing_versions() {
let mut version = HashMap::new();
version.insert("gamestate".to_string(), "[email protected](rust)".to_string());
version.insert("throttle".to_string(), "[email protected](node)".to_string());
Expand Down Expand Up @@ -176,7 +176,7 @@ mod tests {
}

#[test]
fn should_show_features_if_they_have_different_version() {
fn should_show_features_if_version_differs() {
let mut versions_with_features = IndexMap::new();
versions_with_features.insert(
"[email protected](rust)".to_string(),
Expand Down
6 changes: 3 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,12 @@ enum Commands {
#[arg(long)]
loop_infinite: bool,
},
/// Let's you render the game in your browser at http://localhost:8080 by spawning a server and sending stdin via server-sent-events to a JavaScript renderer
/// Let's you render the game in your browser at http://localhost:8080 by spawning a server and sending stdin via server-sent events to a JavaScript renderer
RenderBrowser {
#[arg(long, default_value_t = 8080)]
port: u16,
},
/// Connects to the server spawned by `render-browser` and streams server-sent-events back to the terminal
/// Connects to the server spawned by `render-browser` and streams server-sent events back to the terminal
StreamSse {
#[arg(long, default_value = "http://localhost:8080")]
address: String,
Expand Down Expand Up @@ -92,7 +92,7 @@ impl Into<InitOptions> for CliOptions<'_> {
} else if self.width.is_some() {
size = SizeOption {
width: self.width.unwrap_or(DEFAULT_WIDTH),
height: self.width.unwrap_or(DEFAULT_HEIGHT),
height: self.height.unwrap_or(DEFAULT_HEIGHT),
}
} else if self.fit_terminal.eq(&true) {
let (width, height) = crossterm::terminal::size()
Expand Down

0 comments on commit 8a1c0cd

Please sign in to comment.