mirror of
https://github.com/logos-messaging/js-waku.git
synced 2026-01-08 00:33:12 +00:00
Merge pull request #260 from status-im/remove-chat-message
This commit is contained in:
commit
55a36f2263
2
.github/workflows/examples-ci.yml
vendored
2
.github/workflows/examples-ci.yml
vendored
@ -12,7 +12,7 @@ jobs:
|
|||||||
examples_build_and_test:
|
examples_build_and_test:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
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
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
|
|||||||
@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [Unreleased]
|
## [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.
|
||||||
|
- `ChatMessage` has been moved from js-waku to web-chat example;
|
||||||
|
it is a type used for the [TOY-CHAT](https://rfc.vac.dev/spec/22/) protocol;
|
||||||
|
js-waku users should not build on top if this toy protocol and instead design message data structures appropriate to their use case.
|
||||||
|
|
||||||
## [0.10.0] - 2021-08-06
|
## [0.10.0] - 2021-08-06
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@ -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 }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
4
examples/cli-chat/.gitignore
vendored
4
examples/cli-chat/.gitignore
vendored
@ -1,4 +0,0 @@
|
|||||||
# Generated directories:
|
|
||||||
.nyc_output/
|
|
||||||
node_modules/
|
|
||||||
/tsconfig.tsbuildinfo
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"extension": ["ts"],
|
|
||||||
"spec": "src/**/*.spec.ts",
|
|
||||||
"require": "ts-node/register"
|
|
||||||
}
|
|
||||||
@ -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.
|
|
||||||
10689
examples/cli-chat/package-lock.json
generated
10689
examples/cli-chat/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -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"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -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!$/);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -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;
|
|
||||||
}
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
import startChat from './chat';
|
|
||||||
|
|
||||||
(async () => {
|
|
||||||
await startChat();
|
|
||||||
})();
|
|
||||||
5
examples/cli-chat/src/types/types.d.ts
vendored
5
examples/cli-chat/src/types/types.d.ts
vendored
@ -1,5 +0,0 @@
|
|||||||
declare module 'libp2p-tcp' {
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
const TCP: any;
|
|
||||||
export = TCP;
|
|
||||||
}
|
|
||||||
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -3,6 +3,5 @@
|
|||||||
Here is the list of the code examples and the features they demonstrate:
|
Here is the list of the code examples and the features they demonstrate:
|
||||||
|
|
||||||
- [Web Chat App](web-chat): Group chat, React/TypeScript, Relay, Store.
|
- [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.
|
- [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`.
|
- [Minimal ReactJS Chat App](min-react-js-chat): Group chat, React/JavaScript, Relay, Protobuf using `protons`.
|
||||||
|
|||||||
6
examples/web-chat/buf.gen.yaml
Normal file
6
examples/web-chat/buf.gen.yaml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
version: v1beta1
|
||||||
|
|
||||||
|
plugins:
|
||||||
|
- name: ts_proto
|
||||||
|
out: ./src/proto
|
||||||
|
opt: grpc_js,esModuleInterop=true
|
||||||
5
examples/web-chat/buf.yaml
Normal file
5
examples/web-chat/buf.yaml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
version: v1beta1
|
||||||
|
|
||||||
|
build:
|
||||||
|
roots:
|
||||||
|
- ./src/proto
|
||||||
@ -38,6 +38,8 @@
|
|||||||
"test:spelling": "cspell \"{README.md,.github/*.md,src/**/*.{ts,tsx},public/**/*.html}\" -c ../../.cspell.json",
|
"test:spelling": "cspell \"{README.md,.github/*.md,src/**/*.{ts,tsx},public/**/*.html}\" -c ../../.cspell.json",
|
||||||
"fix:prettier": "prettier \"src/**/*.{ts,tsx}\" \"./*.json\" --write",
|
"fix:prettier": "prettier \"src/**/*.{ts,tsx}\" \"./*.json\" --write",
|
||||||
"fix:lint": "eslint src --ext .ts --ext .tsx --fix",
|
"fix:lint": "eslint src --ext .ts --ext .tsx --fix",
|
||||||
|
"proto": "run-s proto:*",
|
||||||
|
"proto:build": "buf generate",
|
||||||
"js-waku:build": "cd ../; npm run build",
|
"js-waku:build": "cd ../; npm run build",
|
||||||
"predeploy": "run-s js-waku:build build",
|
"predeploy": "run-s js-waku:build build",
|
||||||
"deploy": "gh-pages -d build"
|
"deploy": "gh-pages -d build"
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { ChatMessage, WakuMessage } from 'js-waku';
|
import { WakuMessage } from 'js-waku';
|
||||||
|
import { ChatMessage } from './chat_message';
|
||||||
|
|
||||||
export class Message {
|
export class Message {
|
||||||
public chatMessage: ChatMessage;
|
public chatMessage: ChatMessage;
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
import { ChatMessage, WakuMessage } from 'js-waku';
|
import { WakuMessage } from 'js-waku';
|
||||||
import { ChatContentTopic } from './App';
|
import { ChatContentTopic } from './App';
|
||||||
import ChatList from './ChatList';
|
import ChatList from './ChatList';
|
||||||
import MessageInput from './MessageInput';
|
import MessageInput from './MessageInput';
|
||||||
import { useWaku } from './WakuContext';
|
import { useWaku } from './WakuContext';
|
||||||
import { TitleBar } from '@livechat/ui-kit';
|
import { TitleBar } from '@livechat/ui-kit';
|
||||||
import { Message } from './Message';
|
import { Message } from './Message';
|
||||||
|
import { ChatMessage } from './chat_message';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
messages: Message[];
|
messages: Message[];
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { Reader } from 'protobufjs/minimal';
|
import { Reader } from 'protobufjs/minimal';
|
||||||
|
|
||||||
import * as proto from '../../proto/chat/v2/chat_message';
|
import * as proto from './proto/chat_message';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ChatMessage is used by the various show case waku apps that demonstrates
|
* ChatMessage is used by the various show case waku apps that demonstrates
|
||||||
@ -1,7 +1,5 @@
|
|||||||
syntax = "proto3";
|
syntax = "proto3";
|
||||||
|
|
||||||
package chat.v2;
|
|
||||||
|
|
||||||
message ChatMessage {
|
message ChatMessage {
|
||||||
uint64 timestamp = 1;
|
uint64 timestamp = 1;
|
||||||
string nick = 2;
|
string nick = 2;
|
||||||
@ -2,7 +2,7 @@
|
|||||||
import Long from 'long';
|
import Long from 'long';
|
||||||
import _m0 from 'protobufjs/minimal';
|
import _m0 from 'protobufjs/minimal';
|
||||||
|
|
||||||
export const protobufPackage = 'chat.v2';
|
export const protobufPackage = '';
|
||||||
|
|
||||||
export interface ChatMessage {
|
export interface ChatMessage {
|
||||||
timestamp: number;
|
timestamp: number;
|
||||||
@ -8,8 +8,6 @@ export { WakuMessage } from './lib/waku_message';
|
|||||||
|
|
||||||
export { generatePrivateKey, getPublicKey } from './lib/waku_message/version_1';
|
export { generatePrivateKey, getPublicKey } from './lib/waku_message/version_1';
|
||||||
|
|
||||||
export { ChatMessage } from './lib/chat_message';
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
WakuLightPush,
|
WakuLightPush,
|
||||||
LightPushCodec,
|
LightPushCodec,
|
||||||
|
|||||||
@ -1,26 +0,0 @@
|
|||||||
import { expect } from 'chai';
|
|
||||||
import fc from 'fast-check';
|
|
||||||
|
|
||||||
import { ChatMessage } from './index';
|
|
||||||
|
|
||||||
describe('Chat Message', function () {
|
|
||||||
it('Chat message round trip binary serialization', function () {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(
|
|
||||||
fc.date({ min: new Date(0) }),
|
|
||||||
fc.string(),
|
|
||||||
fc.string(),
|
|
||||||
(timestamp, nick, message) => {
|
|
||||||
const msg = ChatMessage.fromUtf8String(timestamp, nick, message);
|
|
||||||
const buf = msg.encode();
|
|
||||||
const actual = ChatMessage.decode(buf);
|
|
||||||
|
|
||||||
// Date.toString does not include ms, as we loose this precision by design
|
|
||||||
expect(actual.timestamp.toString()).to.eq(timestamp.toString());
|
|
||||||
expect(actual.nick).to.eq(nick);
|
|
||||||
expect(actual.payloadAsUtf8).to.eq(message);
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -8,10 +8,21 @@ import { makeLogFileName, NimWaku, NOISE_KEY_1 } from '../test_utils/';
|
|||||||
import { Waku } from './waku';
|
import { Waku } from './waku';
|
||||||
|
|
||||||
describe('Waku Dial', function () {
|
describe('Waku Dial', function () {
|
||||||
|
let waku: Waku;
|
||||||
|
let nimWaku: NimWaku;
|
||||||
|
|
||||||
|
afterEach(async function () {
|
||||||
|
this.timeout(10_000);
|
||||||
|
|
||||||
|
nimWaku ? nimWaku.stop() : null;
|
||||||
|
waku ? await waku.stop() : null;
|
||||||
|
});
|
||||||
|
|
||||||
describe('Interop: Nim', function () {
|
describe('Interop: Nim', function () {
|
||||||
it('nim connects to js', async function () {
|
it('nim connects to js', async function () {
|
||||||
this.timeout(10_000);
|
this.timeout(10_000);
|
||||||
const waku = await Waku.create({
|
|
||||||
|
waku = await Waku.create({
|
||||||
staticNoiseKey: NOISE_KEY_1,
|
staticNoiseKey: NOISE_KEY_1,
|
||||||
libp2p: {
|
libp2p: {
|
||||||
addresses: { listen: ['/ip4/0.0.0.0/tcp/0'] },
|
addresses: { listen: ['/ip4/0.0.0.0/tcp/0'] },
|
||||||
@ -21,7 +32,7 @@ describe('Waku Dial', function () {
|
|||||||
|
|
||||||
const multiAddrWithId = waku.getLocalMultiaddrWithID();
|
const multiAddrWithId = waku.getLocalMultiaddrWithID();
|
||||||
|
|
||||||
const nimWaku = new NimWaku(makeLogFileName(this));
|
nimWaku = new NimWaku(makeLogFileName(this));
|
||||||
await nimWaku.start({ staticnode: multiAddrWithId });
|
await nimWaku.start({ staticnode: multiAddrWithId });
|
||||||
|
|
||||||
const nimPeers = await nimWaku.peers();
|
const nimPeers = await nimWaku.peers();
|
||||||
@ -38,9 +49,6 @@ describe('Waku Dial', function () {
|
|||||||
const jsPeers = waku.libp2p.peerStore.peers;
|
const jsPeers = waku.libp2p.peerStore.peers;
|
||||||
|
|
||||||
expect(jsPeers.has(nimPeerId.toB58String())).to.be.true;
|
expect(jsPeers.has(nimPeerId.toB58String())).to.be.true;
|
||||||
|
|
||||||
nimWaku.stop();
|
|
||||||
await waku.stop();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -274,6 +274,7 @@ describe('Waku Relay', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
afterEach(async function () {
|
afterEach(async function () {
|
||||||
|
this.timeout(5000);
|
||||||
nimWaku ? nimWaku.stop() : null;
|
nimWaku ? nimWaku.stop() : null;
|
||||||
waku ? await waku.stop() : null;
|
waku ? await waku.stop() : null;
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
export { ChatMessage } from './chat/v2/chat_message';
|
|
||||||
|
|
||||||
export { WakuMessage } from './waku/v2/message';
|
export { WakuMessage } from './waku/v2/message';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
|||||||
@ -13,9 +13,10 @@ import { waitForFile } from './async_fs';
|
|||||||
|
|
||||||
export default async function waitForLine(
|
export default async function waitForLine(
|
||||||
filepath: string,
|
filepath: string,
|
||||||
logLine: string
|
logLine: string,
|
||||||
|
timeout: number
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
await pTimeout(waitForFile(filepath), 2000);
|
await pTimeout(waitForFile(filepath), timeout);
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
fromBeginning: true,
|
fromBeginning: true,
|
||||||
|
|||||||
@ -134,8 +134,8 @@ export class NimWaku {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
dbg("Waiting to see 'RPC Server started' in nim-waku logs");
|
dbg("Waiting to see 'Node setup complete' in nim-waku logs");
|
||||||
await this.waitForLog('RPC Server started');
|
await this.waitForLog('Node setup complete', 9000);
|
||||||
dbg('nim-waku node has been started');
|
dbg('nim-waku node has been started');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,8 +149,8 @@ export class NimWaku {
|
|||||||
this.process = undefined;
|
this.process = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
async waitForLog(msg: string): Promise<void> {
|
async waitForLog(msg: string, timeout: number): Promise<void> {
|
||||||
return waitForLine(this.logPath, msg);
|
return waitForLine(this.logPath, msg, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Calls nim-waku2 JSON-RPC API `get_waku_v2_admin_v1_peers` to check
|
/** Calls nim-waku2 JSON-RPC API `get_waku_v2_admin_v1_peers` to check
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user