Skip to content

Commit

Permalink
refactor: codebase check (#261)
Browse files Browse the repository at this point in the history
Co-authored-by: Jan Lewandowski <[email protected]>
  • Loading branch information
d-roak and JanLewDev authored Dec 3, 2024
1 parent 58a076a commit 76d22c9
Show file tree
Hide file tree
Showing 80 changed files with 1,594 additions and 3,378 deletions.
22 changes: 12 additions & 10 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,23 @@ jobs:
run: |
pnpm install --no-frozen-lockfile
build-example-canvas:
generate-matrix:
runs-on: ubuntu-latest
outputs:
examples: ${{ steps.list-examples.outputs.examples }}
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 9
- shell: bash
- name: List examples
id: list-examples
run: |
pnpm install --no-frozen-lockfile
cd examples/canvas
pnpm build
echo "examples=$(ls -d examples/*/ | xargs -n 1 basename | jq -R -s -c 'split("\n")[:-1]')" >> $GITHUB_OUTPUT
build-example-chat:
build-examples:
needs: generate-matrix
runs-on: ubuntu-latest
strategy:
matrix:
example: ${{ fromJSON(needs.generate-matrix.outputs.examples) }}
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
Expand All @@ -39,5 +41,5 @@ jobs:
- shell: bash
run: |
pnpm install --no-frozen-lockfile
cd examples/chat
cd examples/${{ matrix.example }}
pnpm build
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2024 Topology Foundation
Copyright (c) 2024 Topology

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
24 changes: 13 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div align="center">
<img src="https://avatars.githubusercontent.com/u/157637200" height="128">
<br />
<h1>The TypeScript implementation of the Topology Protocol</h1>
<h1>The TypeScript implementation of Distributed Replicated Programs (DRPs)</h1>
</div>

<div align="center">
Expand All @@ -17,34 +17,36 @@
[![X](https://img.shields.io/badge/X-000000)](https://x.com/topology_gg)
[![Telegram](https://img.shields.io/badge/Telegram-24A1DE)](https://t.me/topologyfrens)
[![Discord](https://img.shields.io/badge/Discord-7289da)](https://discord.gg/GUDGzBP5mn)

</div>

# Overview

This is the official TypeScript implementation of the Topology Protocol. The Topology Protocol is a local-first decentralized protocol for real-time applications. It introduces a new concept for Conflict-free Replicated Objects (CRO), that are built on top of libp2p and composed of CRDTs.
This is the official TypeScript implementation of Distributed Replicated Programs (DRP). DRP is a local-first decentralized protocol for real-time applications. It is built on top of libp2p and with a similar design with CRDTs.

# Specifications

The specifications of the Topology Protocol are shared across different client implementations and can be found in the [specs repository](https://github.com/topology-foundation/specs). Currently the specifications are starting to be written based on this implementation.
The specifications of DRP are shared across different client implementations and can be found in the [specs repository](https://github.com/topology-foundation/specs). Currently the specifications are starting to be written based on this implementation.

# Packages

This repository is a monorepo that contains the following packages:

| Package | Description |
|---------|--------------------------------------------------|
| crdt | CRDT implementations intended to use as builtins |
| network | Network middleware to abstract libp2p |
| node | Topology Node library and CLI |
| object | CRO objects structure implementation |
| Package | Description |
| ---------- | ----------------------------------------------- |
| blueprints | Blueprints of some DRPs that can be freely used |
| logger | Logger for the whole project |
| network | Network middleware to abstract libp2p |
| node | Node for interacting with DRPs library and CLI |
| object | DRP objects structure implementation |

# Examples

All the examples are located in the `examples` directory. Currently, there is only one example, which is a simple canvas where you can paint pixels. You can also look into the [counter-splash](https://github.com/topology-foundation/counter-splash) (demo for EthCC 2024) repository for a more complex example.
All the examples are located in the `examples` directory.

# Usage

This workspae has all packages and examples linked together, so you can run the following commands to start the development:
This workspace has all packages and examples linked together, so you can run the following commands to start the development:

```bash
# pnpm
Expand Down
3 changes: 1 addition & 2 deletions biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
"**/doc/*",
"**/*_pb.js",
"**/*_pb.ts",
"**/bundle/*",
"**/package.json"
"**/bundle/*"
]
},
"linter": {
Expand Down
6 changes: 0 additions & 6 deletions buf.gen.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,3 @@ plugins:
out: .
opt:
- ts_proto_opt=esModuleInterop=true
inputs:
- directory: ./packages
exclude_paths:
- packages/node
- packages/network/node_modules
- packages/object/node_modules
6 changes: 3 additions & 3 deletions buf.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
version: v2
modules:
- path: packages/node/src/proto
name: buf.build/topology/node
name: buf.build/drp/node

- path: packages/object/src/proto
name: buf.build/topology/object
name: buf.build/drp/object

- path: packages/network/src/proto
name: buf.build/topology/network
name: buf.build/drp/network
2 changes: 1 addition & 1 deletion examples/canvas/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Topology - Canvas</title>
<title>DRP - Canvas</title>
</head>

<body>
Expand Down
45 changes: 18 additions & 27 deletions examples/canvas/package.json
Original file line number Diff line number Diff line change
@@ -1,29 +1,20 @@
{
"name": "ts-topology-examples-canvas",
"version": "0.3.1",
"license": "MIT",
"scripts": {
"build": "vite build",
"clean": "rm -rf dist/ node_modules/",
"dev": "vite serve",
"start": "ts-node ./src/index.ts"
},
"dependencies": {
"@topology-foundation/blueprints": "0.3.1",
"@topology-foundation/network": "0.3.1",
"@topology-foundation/node": "0.3.1",
"@topology-foundation/object": "0.3.1",
"crypto-browserify": "^3.12.0",
"process": "^0.11.10",
"stream-browserify": "^3.0.0",
"ts-node": "^10.9.2",
"vm-browserify": "^1.1.2"
},
"devDependencies": {
"@types/node": "^22.5.4",
"ts-loader": "^9.3.1",
"typescript": "^5.5.4",
"vite": "^6.0.0",
"vite-plugin-node-polyfills": "^0.22.0"
}
"name": "ts-drp-examples-canvas",
"version": "0.3.1",
"license": "MIT",
"scripts": {
"build": "vite build",
"clean": "rm -rf dist/ node_modules/",
"dev": "vite serve"
},
"dependencies": {
"@ts-drp/node": "0.3.1",
"@ts-drp/object": "0.3.1"
},
"devDependencies": {
"@types/node": "^22.5.4",
"typescript": "^5.5.4",
"vite": "^5.4.9",
"vite-plugin-node-polyfills": "^0.22.0"
}
}
43 changes: 21 additions & 22 deletions examples/canvas/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { TopologyNode } from "@topology-foundation/node";
import type { TopologyObject } from "@topology-foundation/object";
import { DRPNode } from "@ts-drp/node";
import type { DRPObject } from "@ts-drp/object";
import { Canvas } from "./objects/canvas";

const node = new TopologyNode();
let topologyObject: TopologyObject;
let canvasCRO: Canvas;
const node = new DRPNode();
let drpObject: DRPObject;
let canvasDRP: Canvas;
let peers: string[] = [];
let discoveryPeers: string[] = [];
let objectPeers: string[] = [];
Expand All @@ -23,10 +23,10 @@ const render = () => {
);
object_element.innerHTML = `[${objectPeers.join(", ")}]`;
(<HTMLSpanElement>document.getElementById("canvasId")).innerText =
topologyObject?.id;
drpObject?.id;

if (!canvasCRO) return;
const canvas = canvasCRO.canvas;
if (!canvasDRP) return;
const canvas = canvasDRP.canvas;
for (let x = 0; x < canvas.length; x++) {
for (let y = 0; y < canvas[x].length; y++) {
const pixel = document.getElementById(`${x}-${y}`);
Expand All @@ -45,19 +45,18 @@ function paint_pixel(pixel: HTMLDivElement) {
random_int(256),
random_int(256),
];
canvasCRO.paint([x, y], painting);
const [r, g, b] = canvasCRO.pixel(x, y).color();
canvasDRP.paint([x, y], painting);
const [r, g, b] = canvasDRP.pixel(x, y).color();
pixel.style.backgroundColor = `rgb(${r}, ${g}, ${b})`;
}

async function createConnectHandlers() {
node.addCustomGroupMessageHandler(topologyObject.id, (e) => {
if (topologyObject)
objectPeers = node.networkNode.getGroupPeers(topologyObject.id);
node.addCustomGroupMessageHandler(drpObject.id, (e) => {
if (drpObject) objectPeers = node.networkNode.getGroupPeers(drpObject.id);
render();
});

node.objectStore.subscribe(topologyObject.id, (_, _obj) => {
node.objectStore.subscribe(drpObject.id, (_, _obj) => {
render();
});
}
Expand Down Expand Up @@ -86,36 +85,36 @@ async function init() {

node.addCustomGroupMessageHandler("", (e) => {
peers = node.networkNode.getAllPeers();
discoveryPeers = node.networkNode.getGroupPeers("topology::discovery");
discoveryPeers = node.networkNode.getGroupPeers("drp::discovery");
render();
});

const create_button = <HTMLButtonElement>document.getElementById("create");
create_button.addEventListener("click", async () => {
topologyObject = await node.createObject(new Canvas(5, 10));
canvasCRO = topologyObject.cro as Canvas;
drpObject = await node.createObject(new Canvas(5, 10));
canvasDRP = drpObject.drp as Canvas;

createConnectHandlers();
render();
});

const connect_button = <HTMLButtonElement>document.getElementById("connect");
connect_button.addEventListener("click", async () => {
const croId = (<HTMLInputElement>document.getElementById("canvasIdInput"))
const drpId = (<HTMLInputElement>document.getElementById("canvasIdInput"))
.value;
try {
topologyObject = await node.createObject(
drpObject = await node.createObject(
new Canvas(5, 10),
croId,
drpId,
undefined,
true,
);
canvasCRO = topologyObject.cro as Canvas;
canvasDRP = drpObject.drp as Canvas;

createConnectHandlers();
render();
} catch (e) {
console.error("Error while connecting with CRO", croId, e);
console.error("Error while connecting with DRP", drpId, e);
}
});
}
Expand Down
6 changes: 3 additions & 3 deletions examples/canvas/src/objects/canvas.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import {
ActionType,
type CRO,
type DRP,
type Operation,
type ResolveConflictsType,
SemanticsType,
} from "@topology-foundation/object";
} from "@ts-drp/object";
import { Pixel } from "./pixel";

export class Canvas implements CRO {
export class Canvas implements DRP {
operations: string[] = ["splash", "paint"];
semanticsType: SemanticsType = SemanticsType.pair;

Expand Down
2 changes: 1 addition & 1 deletion examples/canvas/vite.config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default defineConfig({
},
resolve: {
alias: {
"@topology-foundation": path.resolve(__dirname, "../../packages"),
"@ts-drp": path.resolve(__dirname, "../../packages"),
},
},
});
22 changes: 6 additions & 16 deletions examples/chat/README.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,17 @@
# Topology Protocol Example
# DRP Example

This is an example of Topology Protocol usage in a chat system where a user can create or connect to a chat room, send and read the messages sent in the group chat.
This is an example of a DRP usage in a chat system where a user can create or connect to a chat room, send and read the messages sent in the group chat.

## Specifics

Messages are represented as strings in the format (timestamp, content, senderId). Chat is a class which extends TopologyObject and has Gset\<string> as an attribute to store the list of messages.
Messages are represented as strings in the format (timestamp, content, senderId). Chat is a class which extends DRPObject and stores the list of messages.

## How to run locally

After cloning the repository, run the following commands:

```bash
cd ts-topology/examples/chat
yarn
yarn build
yarn dev
```

Debugging is made easier by setting the mode in `webpack.config.js` to "development":

```js
module.exports = {
mode: "development",
...
}
cd ts-drp/examples/chat
pnpm i
pnpm dev
```
27 changes: 0 additions & 27 deletions examples/chat/asconfig.json

This file was deleted.

4 changes: 2 additions & 2 deletions examples/chat/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Topology - Chat</title>
<title>DRP - Chat</title>
</head>
<body>
<div>
<h1>Topology Protocol - Chat</h1>
<h1>DRP - Chat</h1>
<p>Current peer ID <span id="peerId"></span></p>
<p>Connected to <span id="chatId"></span></p>
<p>peers: <span id="peers"></span></p>
Expand Down
Loading

0 comments on commit 76d22c9

Please sign in to comment.