Remove cli-chat example

The focus of this library is on Web environment; Several examples now
cover usage of Waku Relay and Waku Store; web-chat POC should be
preferred to use the [TOY-CHAT](https://rfc.vac.dev/spec/22/) protocol.
This commit is contained in:
Franck Royer 2021-08-06 16:59:54 +10:00
parent 0431088115
commit 0c3995a810
No known key found for this signature in database
GPG Key ID: A82ED75A8DFC50A4
14 changed files with 6 additions and 11130 deletions

View File

@ -12,7 +12,7 @@ jobs:
examples_build_and_test:
strategy:
matrix:
example: [ cli-chat, web-chat, eth-dm, min-react-js-chat ]
example: [ web-chat, eth-dm, min-react-js-chat ]
runs-on: ubuntu-latest
steps:

View File

@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Removed
- Examples (cli-chat): The focus of this library is Web environment;
Several examples now cover usage of Waku Relay and Waku Store making cli-chat example obsolete;
web-chat POC should be preferred to use the [TOY-CHAT](https://rfc.vac.dev/spec/22/) protocol.
## [0.10.0] - 2021-08-06
### Added

View File

@ -1,35 +0,0 @@
{
"root": true,
"parser": "@typescript-eslint/parser",
"parserOptions": { "project": "./tsconfig.json" },
"env": { "es6": true },
"ignorePatterns": ["node_modules"],
"plugins": ["import", "eslint-comments", "functional"],
"extends": [
"eslint:recommended",
"plugin:eslint-comments/recommended",
"plugin:@typescript-eslint/recommended",
"plugin:import/typescript",
"prettier",
"prettier/@typescript-eslint"
],
"globals": { "BigInt": true, "console": true, "WebAssembly": true },
"rules": {
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"eslint-comments/disable-enable-pair": [
"error",
{ "allowWholeFile": true }
],
"eslint-comments/no-unused-disable": "error",
"import/order": [
"error",
{ "newlines-between": "always", "alphabetize": { "order": "asc" } }
],
"no-constant-condition": ["error", { "checkLoops": false }],
"sort-imports": [
"error",
{ "ignoreDeclarationSort": true, "ignoreCase": true }
]
}
}

View File

@ -1,4 +0,0 @@
# Generated directories:
.nyc_output/
node_modules/
/tsconfig.tsbuildinfo

View File

@ -1,5 +0,0 @@
{
"extension": ["ts"],
"spec": "src/**/*.spec.ts",
"require": "ts-node/register"
}

View File

@ -1,35 +0,0 @@
# CLI Chat App
**Demonstrates**:
- Group chat
- Node JS/TypeScript
- Waku Relay
- Waku Light Push
- Waku Store
A node chat app is provided as a working example of the library.
It implements [Waku v2 Toy Chat](https://rfc.vac.dev/spec/22/) protocol.
Find the code in the [examples folder](https://github.com/status-im/js-waku/tree/main/examples/cli-chat).
To run the chat app, first ensure you have [Node.js](https://nodejs.org/en/) v14 or above:
```shell
node --version
```
Then, install and run:
```shell
git clone https://github.com/status-im/js-waku/ ; cd js-waku
npm install # Install dependencies for js-waku
npm run build # Build js-waku
cd examples/cli-chat
npm install # Install dependencies for the cli app
npm run start -- --autoDial
```
You can also specify an optional `listenAddr` parameter (.e.g `--listenAddr /ip4/0.0.0.0/tcp/7777/ws`).
This is only useful if you want a remote node to dial to your chat app,
it is not necessary in normal usage when you just connect to the fleet.

File diff suppressed because it is too large Load Diff

View File

@ -1,75 +0,0 @@
{
"name": "js-waku-cli-chat",
"version": "0.1.0",
"description": "A NodeJS CLI Chat App powered by js-waku",
"main": "./index.ts",
"repository": "https://github.com/status-im/js-waku",
"license": "MIT OR Apache-2.0",
"keywords": [
"waku",
"decentralised",
"communication"
],
"scripts": {
"build": "run-s build:*",
"build:main": "tsc -p tsconfig.json",
"fix": "run-s fix:*",
"fix:prettier": "prettier \"src/**/*.ts\" \"./*.json\" --write",
"fix:lint": "eslint src --ext .ts --fix",
"start": "ts-node src/index.ts",
"test": "run-s build test:*",
"test:lint": "eslint src --ext .ts",
"test:prettier": "prettier \"src/**/*.ts\" \"./*.json\" --list-different",
"test:spelling": "cspell \"{README.md,src/**/*.ts}\" -c ../../.cspell.json",
"test:unit": "nyc --silent mocha",
"watch:build": "tsc -p tsconfig.json -w",
"watch:test": "nyc --silent mocha --watch",
"version": "standard-version",
"reset-hard": "git clean -dfx && git reset --hard && npm i"
},
"engines": {
"node": ">=14"
},
"dependencies": {
"js-waku": "../../build/main",
"libp2p-tcp": "^0.17.0",
"prompt-sync": "^4.2.0"
},
"devDependencies": {
"@istanbuljs/nyc-config-typescript": "^1.0.1",
"@types/app-root-path": "^1.2.4",
"@types/chai": "^4.2.15",
"@types/mocha": "^8.2.2",
"@types/node": "^14.14.31",
"@typescript-eslint/eslint-plugin": "^4.0.1",
"@typescript-eslint/parser": "^4.0.1",
"chai": "^4.3.4",
"cspell": "^4.1.0",
"eslint": "^7.8.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-eslint-comments": "^3.2.0",
"eslint-plugin-functional": "^3.0.2",
"eslint-plugin-import": "^2.22.0",
"mocha": "^8.3.2",
"npm-run-all": "^4.1.5",
"nyc": "^15.1.0",
"prettier": "^2.1.1",
"ts-node": "^9.1.1",
"typedoc": "^0.20.29",
"typescript": "^4.0.2"
},
"prettier": {
"singleQuote": true
},
"files": [
"!**/*.spec.*",
"!**/*.json",
"README.md"
],
"nyc": {
"extends": "@istanbuljs/nyc-config-typescript",
"exclude": [
"**/*.spec.js"
]
}
}

View File

@ -1,17 +0,0 @@
import { expect } from 'chai';
import { ChatMessage } from 'js-waku';
import { formatMessage } from './chat';
describe('CLI Chat app', () => {
it('Format message', () => {
const date = new Date(234325324);
const chatMessage = ChatMessage.fromUtf8String(
date,
'alice',
'Hello world!'
);
expect(formatMessage(chatMessage)).to.match(/^<.*> alice: Hello world!$/);
});
});

View File

@ -1,204 +0,0 @@
import readline from 'readline';
import util from 'util';
import {
ChatMessage,
Direction,
Environment,
getStatusFleetNodes,
Protocol,
StoreCodec,
Waku,
WakuMessage,
} from 'js-waku';
import TCP from 'libp2p-tcp';
import { multiaddr, Multiaddr } from 'multiaddr';
const ChatContentTopic = '/toy-chat/2/huilong/proto';
export default async function startChat(): Promise<void> {
let opts = processArguments();
if (!opts) return;
if (opts.autoDial) {
opts = await addFleetNodes(opts);
}
const waku = await Waku.create({
libp2p: {
addresses: { listen: [opts.listenAddr] },
modules: { transport: [TCP] },
},
});
console.log('PeerId: ', waku.libp2p.peerId.toB58String());
console.log('Listening on ');
waku.libp2p.multiaddrs.forEach((address) => {
console.log(`\t- ${address}`);
});
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
let nick = 'js-waku';
try {
const question = util.promisify(rl.question).bind(rl);
// Looks like wrong type definition of promisify is picked.
// May be related to https://github.com/DefinitelyTyped/DefinitelyTyped/issues/20497
nick = ((await question(
'Please choose a nickname: '
)) as unknown) as string;
} catch (e) {
console.log('Using default nick. Due to ', e);
}
console.log(`Hi, ${nick}!`);
waku.relay.addObserver(
(message) => {
if (message.payload) {
const chatMsg = ChatMessage.decode(message.payload);
console.log(formatMessage(chatMsg));
}
},
[ChatContentTopic]
);
await Promise.all(
opts.staticNodes.map((addr) => {
console.log(`Dialing ${addr}`);
return waku.dial(addr);
})
);
// If we connect to a peer with WakuStore, we run the protocol
// TODO: Instead of doing it `once` it should always be done but
// only new messages should be printed
waku.libp2p.peerStore.once(
'change:protocols',
async ({ peerId, protocols }) => {
if (protocols.includes(StoreCodec)) {
console.log(
`Retrieving archived messages from ${peerId.toB58String()}`
);
const messages = await waku.store.queryHistory({
peerId,
contentTopics: [ChatContentTopic],
direction: Direction.FORWARD,
});
messages?.map((msg) => {
if (msg.payload) {
const chatMsg = ChatMessage.decode(msg.payload);
console.log(formatMessage(chatMsg));
}
});
}
}
);
console.log('Ready to chat!');
rl.prompt();
for await (const line of rl) {
rl.prompt();
const chatMessage = ChatMessage.fromUtf8String(new Date(), nick, line);
const msg = await WakuMessage.fromBytes(
chatMessage.encode(),
ChatContentTopic,
{
timestamp: new Date(),
}
);
if (opts.lightPush) {
await waku.lightPush.push(msg);
} else {
await waku.relay.send(msg);
}
}
}
interface Options {
staticNodes: Multiaddr[];
listenAddr: string;
autoDial: boolean;
prod: boolean;
lightPush: boolean;
}
function processArguments(): Options | null {
const passedArgs = process.argv.slice(2);
let opts: Options = {
listenAddr: '/ip4/0.0.0.0/tcp/0',
staticNodes: [],
autoDial: false,
prod: false,
lightPush: false,
};
while (passedArgs.length) {
const arg = passedArgs.shift();
switch (arg) {
case `--help`:
console.log('Usage:');
console.log(' --help This help message');
console.log(
' --staticNode {multiaddr} Connect to this static node, can be set multiple time'
);
console.log(' --listenAddr {addr} Listen on this address');
console.log(' --autoDial Automatically dial Status fleet nodes');
console.log(
' --prod With `autoDial`, connect ot Status prod fleet (test fleet is dialed if not set)'
);
console.log(
' --lightPush Use Waku v2 Light Push protocol to send messages, instead of Waku v2 relay'
);
return null;
case '--staticNode':
opts.staticNodes.push(multiaddr(passedArgs.shift()!));
break;
case '--listenAddr':
opts = Object.assign(opts, { listenAddr: passedArgs.shift() });
break;
case '--autoDial':
opts.autoDial = true;
break;
case '--prod':
opts.prod = true;
break;
case '--lightPush':
opts.lightPush = true;
break;
default:
console.log(`Unsupported argument: ${arg}`);
process.exit(1);
}
}
return opts;
}
export function formatMessage(chatMsg: ChatMessage): string {
const timestamp = chatMsg.timestamp.toLocaleString([], {
month: 'short',
day: 'numeric',
hour: 'numeric',
minute: '2-digit',
hour12: false,
});
return `<${timestamp}> ${chatMsg.nick}: ${chatMsg.payloadAsUtf8}`;
}
async function addFleetNodes(opts: Options): Promise<Options> {
await getStatusFleetNodes(
opts.prod ? Environment.Prod : Environment.Test,
Protocol.tcp
).then((nodes) =>
nodes.map((addr) => {
opts.staticNodes.push(multiaddr(addr));
})
);
return opts;
}

View File

@ -1,5 +0,0 @@
import startChat from './chat';
(async () => {
await startChat();
})();

View File

@ -1,5 +0,0 @@
declare module 'libp2p-tcp' {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const TCP: any;
export = TCP;
}

View File

@ -1,54 +0,0 @@
{
"compilerOptions": {
"incremental": true,
"target": "es2017",
"rootDir": "src",
"noEmit": true,
"moduleResolution": "node",
"module": "commonjs",
"declaration": true,
"inlineSourceMap": true,
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
"resolveJsonModule": true /* Include modules imported with .json extension. */,
"strict": true /* Enable all strict type-checking options. */,
/* Strict Type-Checking Options */
"noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */,
"strictNullChecks": true /* Enable strict null checks. */,
"strictFunctionTypes": true /* Enable strict checking of function types. */,
"strictPropertyInitialization": true /* Enable strict checking of property initialization in classes. */,
"noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */,
"alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */,
/* Additional Checks */
"noUnusedLocals": true /* Report errors on unused locals. */,
"noUnusedParameters": true /* Report errors on unused parameters. */,
"noImplicitReturns": true /* Report error when not all code paths in function return a value. */,
"noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */,
"forceConsistentCasingInFileNames": true,
/* Debugging Options */
"traceResolution": false /* Report module resolution log messages. */,
"listEmittedFiles": false /* Print names of generated files part of the compilation. */,
"listFiles": false /* Print names of files part of the compilation. */,
"pretty": true /* Stylize errors and messages using color and context. */,
// Due to broken types in indirect dependencies
"skipLibCheck": true,
/* Experimental Options */
// "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */,
// "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */,
"lib": ["es2017"],
"types": ["node", "mocha"],
"typeRoots": ["node_modules/@types", "src/types"]
},
"include": ["src/**/*.ts"],
"exclude": ["node_modules/**"],
"compileOnSave": false,
"ts-node": {
"files": true
}
}

View File

@ -3,6 +3,5 @@
Here is the list of the code examples and the features they demonstrate:
- [Web Chat App](web-chat): Group chat, React/TypeScript, Relay, Store.
- [CLI Chat App](cli-chat): Group chat, Node JS/TypeScript, Relay, Light Push, Store.
- [Ethereum Direct Message Web App](eth-dm): Private Messaging, React/TypeScript, Light Push, Signature with Web3, Asymmetric Encryption.
- [Minimal ReactJS Chat App](min-react-js-chat): Group chat, React/JavaScript, Relay, Protobuf using `protons`.