Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
rennokki committed Jan 20, 2024
1 parent cdd6b73 commit bcd7507
Show file tree
Hide file tree
Showing 15 changed files with 230 additions and 43 deletions.
16 changes: 16 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
enable-beta-ecosystems: true
version: 2

updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
time: "05:00"
labels:
- "semver:minor"
- "semver:major"
groups:
dev:
dependency-type: development
52 changes: 52 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: CI

on:
push:
branches:
- main
pull_request:

jobs:
main:
runs-on: ubuntu-latest

name: Testing (Node ${{ matrix.node-version }})

strategy:
fail-fast: false
matrix:
node-version:
- 18.x
- 20.x

steps:
- uses: actions/checkout@v4
name: Checkout
with:
fetch-depth: 0

- uses: actions/setup-node@v3
name: Setup Node.js ${{ matrix.node-version }}
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'

- name: Cache NPM dependencies
uses: actions/cache@v3
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: Install dependencies
run: npm ci

# This is needed for nx affected to work when CI is running on a PR
- uses: nrwl/nx-set-shas@v3
name: Set NX's SHAs

- name: Run tests
run: |
npx nx format:check
npx nx affected -t lint,test,build --parallel=3 --configuration=ci
5 changes: 4 additions & 1 deletion nx.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@
"!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)",
"!{projectRoot}/tsconfig.spec.json"
],
"sharedGlobals": []
"sharedGlobals": [
"{workspaceRoot}/.github/workflows/ci.yml",
"{workspaceRoot}/.github/dependabot.yml"
]
},
"nxCloudAccessToken": "Y2YxODE0MzktNGEyNS00YWIxLThkMTItNTlkYWY1MDQwMDdifHJlYWQtd3JpdGU="
}
3 changes: 2 additions & 1 deletion packages/connections/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
"name": "@soketi/connections",
"version": "0.0.1",
"dependencies": {
"tslib": "^2.3.0"
"tslib": "^2.3.0",
"@soketi/utils": "*"
},
"type": "module",
"main": "./src/index.js",
Expand Down
8 changes: 4 additions & 4 deletions packages/connections/src/lib/connection.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ beforeEach(() => {
closes.length = 0;
});

const newConnection = async (id: string, namespace = 'default') => {
const newConnection = async (id: string, namespace = 'radio:5ghz') => {
const nativeConn = {
send: vitest.fn(),
close: vitest.fn(),
Expand All @@ -38,15 +38,15 @@ const newConnection = async (id: string, namespace = 'default') => {

describe('connection', () => {
it('works', async () => {
const conn = await newConnection('1');
const conn = await newConnection('probe:voyager-1');

expect(conn).toBeTruthy();

await conn.sendThenClose('hello', 1000, 'bye');

await new Promise(resolve => setTimeout(resolve, 1000));

expect(messages).toEqual([{ message: 'hello', id: '1', namespace: 'default' }]);
expect(closes).toEqual([{ code: 1000, reason: 'bye', id: '1', namespace: 'default' }]);
expect(messages).toEqual([{ message: 'hello', id: 'probe:voyager-1', namespace: 'radio:5ghz' }]);
expect(closes).toEqual([{ code: 1000, reason: 'bye', id: 'probe:voyager-1', namespace: 'radio:5ghz' }]);
});
});
36 changes: 18 additions & 18 deletions packages/connections/src/lib/connections-pool.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ beforeEach(() => {
closes.length = 0;
});

const newConnection = async (id: string, namespace = 'default') => {
const newConnection = async (id: string, namespace = 'radio:5ghz') => {
const nativeConn = {
send: vitest.fn(),
close: vitest.fn(),
Expand All @@ -40,52 +40,52 @@ const newConnection = async (id: string, namespace = 'default') => {
describe('connections pool', () => {
it('works', async () => {
const pool = new ConnectionsPool();
const conn1 = await newConnection('1');
const conn2 = await newConnection('2');
const conn3 = await newConnection('3', 'other');
const conn1 = await newConnection('probe:voyager-1');
const conn2 = await newConnection('earth:jfk-space-center');
const conn3 = await newConnection('planet:neptune', 'radio:40ghz');

expect(pool).toBeTruthy();

await pool.newConnection(conn1);
await pool.newConnection(conn2);
await pool.newConnection(conn3);

await pool.broadcastJsonMessage('default', {
await pool.broadcastJsonMessage('radio:5ghz', {
type: 'hello',
data: 'world',
});

expect(messages).toEqual([
{ message: JSON.stringify({ type: 'hello', data: 'world' }), id: '1', namespace: 'default' },
{ message: JSON.stringify({ type: 'hello', data: 'world' }), id: '2', namespace: 'default' },
{ message: JSON.stringify({ type: 'hello', data: 'world' }), id: 'probe:voyager-1', namespace: 'radio:5ghz' },
{ message: JSON.stringify({ type: 'hello', data: 'world' }), id: 'earth:jfk-space-center', namespace: 'radio:5ghz' },
]);

await pool.broadcastJsonMessage('other', {
await pool.broadcastJsonMessage('radio:40ghz', {
type: 'hello',
data: 'world',
});

expect(messages).toEqual([
{ message: JSON.stringify({ type: 'hello', data: 'world' }), id: '1', namespace: 'default' },
{ message: JSON.stringify({ type: 'hello', data: 'world' }), id: '2', namespace: 'default' },
{ message: JSON.stringify({ type: 'hello', data: 'world' }), id: '3', namespace: 'other' },
{ message: JSON.stringify({ type: 'hello', data: 'world' }), id: 'probe:voyager-1', namespace: 'radio:5ghz' },
{ message: JSON.stringify({ type: 'hello', data: 'world' }), id: 'earth:jfk-space-center', namespace: 'radio:5ghz' },
{ message: JSON.stringify({ type: 'hello', data: 'world' }), id: 'planet:neptune', namespace: 'radio:40ghz' },
]);

await pool.closeAll('default', 1000, 'bye');
await pool.closeAll('radio:5ghz', 1000, 'bye');
await new Promise(resolve => setTimeout(resolve, 1000));

expect(closes).toEqual([
{ code: 1000, reason: 'bye', id: '1', namespace: 'default' },
{ code: 1000, reason: 'bye', id: '2', namespace: 'default' },
{ code: 1000, reason: 'bye', id: 'probe:voyager-1', namespace: 'radio:5ghz' },
{ code: 1000, reason: 'bye', id: 'earth:jfk-space-center', namespace: 'radio:5ghz' },
]);

await pool.closeAll('other', 1000, 'bye');
await pool.closeAll('radio:40ghz', 1000, 'bye');
await new Promise(resolve => setTimeout(resolve, 1000));

expect(closes).toEqual([
{ code: 1000, reason: 'bye', id: '1', namespace: 'default' },
{ code: 1000, reason: 'bye', id: '2', namespace: 'default' },
{ code: 1000, reason: 'bye', id: '3', namespace: 'other' },
{ code: 1000, reason: 'bye', id: 'probe:voyager-1', namespace: 'radio:5ghz' },
{ code: 1000, reason: 'bye', id: 'earth:jfk-space-center', namespace: 'radio:5ghz' },
{ code: 1000, reason: 'bye', id: 'planet:neptune', namespace: 'radio:40ghz' },
]);
});
});
6 changes: 5 additions & 1 deletion packages/gossiper/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
"name": "@soketi/gossiper",
"version": "0.0.1",
"dependencies": {
"tslib": "^2.3.0"
"tslib": "^2.3.0",
"@soketi/connections": "*",
"uint8arrays": "4.0.10",
"@libp2p/interface": "1.1.2",
"@soketi/p2p": "*"
},
"type": "module",
"main": "./src/index.js",
Expand Down
75 changes: 72 additions & 3 deletions packages/gossiper/src/lib/gossiper.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,76 @@
import { gossiper } from './gossiper';
import { DefaultPayload, Gossiper } from './gossiper';

class MockedGossiper extends Gossiper {
announcements: Parameters<Gossiper['announce']>[] = [];

constructor() {
super();
}

override announce(
namespace: string,
event: string,
payload: DefaultPayload<string, Record<string, unknown>>
): Promise<void> {
this.announcements.push([namespace, event, payload]);
return Promise.resolve();
}
}

describe('gossiper', () => {
it('should work', () => {
expect(gossiper()).toEqual('gossiper');
it('should announce', async () => {
const gossiper = new MockedGossiper();

const passedArgs: Parameters<Gossiper['announce']> = [
'radio:10ghz',
'new-message',
{
planet: 'earth',
sender: 'space-center:jfk',
command: 'Play Despacito',
},
];

await gossiper.announce(...passedArgs);
expect(gossiper.announcements).toHaveLength(1);

const [namespace, event, payload] = gossiper.announcements[0];

expect(namespace).toBe(passedArgs[0]);
expect(event).toBe(passedArgs[1]);
expect(payload).toEqual(passedArgs[2]);
});

// eslint-disable-next-line no-async-promise-executor
it('subscribeToNamespace works', () => new Promise<void>(async done => {
const gossiper = new MockedGossiper();

await gossiper.subscribeToNamespace('radio:10ghz', async ({ event, payload }) => {
expect(event).toBe('new-message');
expect(payload).toEqual({
planet: 'earth',
sender: 'space-center:jfk',
command: 'Play Despacito',
});
done();
});

const passedArgs: Parameters<Gossiper['announce']> = [
'radio:10ghz',
'new-message',
{
planet: 'earth',
sender: 'space-center:jfk',
command: 'Play Despacito',
},
];

await gossiper.announce(...passedArgs);
expect(gossiper.announcements).toHaveLength(1);

await gossiper.handleAnnouncement(passedArgs[0], {
event: passedArgs[1],
payload: passedArgs[2],
});
}));
});
21 changes: 20 additions & 1 deletion packages/p2p/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,26 @@
"name": "@soketi/p2p",
"version": "0.0.1",
"dependencies": {
"tslib": "^2.3.0"
"tslib": "^2.3.0",
"libp2p": "1.2.0",
"helia": "^3.0.1",
"blockstore-core": "4.3.10",
"datastore-core": "9.2.7",
"@helia/block-brokers": "1.0.0",
"@libp2p/tcp": "^9.0.11",
"@libp2p/websockets": "^8.0.11",
"@libp2p/identify": "^1.0.10",
"@libp2p/mplex": "^10.0.11",
"@libp2p/mdns": "^10.0.11",
"@libp2p/autonat": "^1.0.8",
"@libp2p/dcutr": "^1.0.8",
"@libp2p/kad-dht": "^12.0.3",
"@libp2p/circuit-relay-v2": "^1.0.11",
"@libp2p/prometheus-metrics": "^3.0.11",
"@libp2p/perf": "^3.0.11",
"@libp2p/pnet": "^1.0.1",
"@chainsafe/libp2p-noise": "^14.1.0",
"@chainsafe/libp2p-gossipsub": "^11.0.1"
},
"type": "module",
"main": "./src/index.js",
Expand Down
3 changes: 2 additions & 1 deletion packages/routing/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
"name": "@soketi/routing",
"version": "0.0.1",
"dependencies": {
"tslib": "^2.3.0"
"tslib": "^2.3.0",
"@soketi/connections": "*"
},
"type": "module",
"main": "./src/index.js",
Expand Down
12 changes: 6 additions & 6 deletions packages/routing/src/lib/websockets-router.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ beforeEach(() => {
closes.length = 0;
});

const newConnection = async (id: string, namespace = 'default') => {
const newConnection = async (id: string, namespace = 'radio:5ghz') => {
const nativeConn = {
send: vitest.fn(),
close: vitest.fn(),
Expand Down Expand Up @@ -65,7 +65,7 @@ describe('websockets router', () => {
await connections.removeConnection(conn);
});

const conn = await newConnection('1');
const conn = await newConnection('probe:voyager-1');

await router.handleNewConnection(conn);
expect(connections.connections.size).toEqual(1);
Expand Down Expand Up @@ -93,13 +93,13 @@ describe('websockets router', () => {
await conn.send(message);
});

const conn = await newConnection('1');
const conn = await newConnection('probe:voyager-1');

await router.handleNewConnection(conn);
expect(connections.connections.size).toEqual(1);

await router.handleMessage(conn, 'hello');
expect(messages).toEqual([{ message: 'hello', id: '1', namespace: 'default' }]);
expect(messages).toEqual([{ message: 'hello', id: 'probe:voyager-1', namespace: 'radio:5ghz' }]);

await router.handleConnectionClosed(conn);
expect(connections.connections.size).toEqual(0);
Expand All @@ -124,13 +124,13 @@ describe('websockets router', () => {
await conn.send(error);
});

const conn = await newConnection('1');
const conn = await newConnection('probe:voyager-1');

await router.handleNewConnection(conn);
expect(connections.connections.size).toEqual(1);

await router.handleError(conn, 'hello');
expect(messages).toEqual([{ message: 'hello', id: '1', namespace: 'default' }]);
expect(messages).toEqual([{ message: 'hello', id: 'probe:voyager-1', namespace: 'radio:5ghz' }]);

await router.handleConnectionClosed(conn);
expect(connections.connections.size).toEqual(0);
Expand Down
8 changes: 7 additions & 1 deletion packages/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@
"name": "@soketi/server",
"version": "0.0.1",
"dependencies": {
"tslib": "^2.3.0"
"tslib": "^2.3.0",
"@soketi/gossiper": "*",
"@soketi/connections": "*",
"@soketi/brain": "*",
"@soketi/p2p": "*",
"@soketi/utils": "*",
"uWebSockets.js": "*"
},
"type": "module",
"main": "./src/index.js",
Expand Down
Loading

0 comments on commit bcd7507

Please sign in to comment.