{"id":13738946,"url":"https://github.com/redhog/cliqueclique","last_synced_at":"2025-04-15T07:23:35.704Z","repository":{"id":1272153,"uuid":"1211343","full_name":"redhog/cliqueclique","owner":"redhog","description":"p2p forum on top of i2p","archived":false,"fork":false,"pushed_at":"2013-04-06T21:07:16.000Z","size":13721,"stargazers_count":7,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-28T17:48:06.728Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://redhog.org/cliqueclique","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/redhog.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2010-12-31T19:14:22.000Z","updated_at":"2025-01-16T22:22:34.000Z","dependencies_parsed_at":"2022-08-16T13:20:06.279Z","dependency_job_id":null,"html_url":"https://github.com/redhog/cliqueclique","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redhog%2Fcliqueclique","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redhog%2Fcliqueclique/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redhog%2Fcliqueclique/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redhog%2Fcliqueclique/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/redhog","download_url":"https://codeload.github.com/redhog/cliqueclique/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249024601,"owners_count":21200151,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-03T04:00:21.370Z","updated_at":"2025-04-15T07:23:35.685Z","avatar_url":"https://github.com/redhog.png","language":"JavaScript","funding_links":[],"categories":["Projects using I2P"],"sub_categories":["Forum / Blog"],"readme":"A distributed forum / social media platform\n\n    git clone git://github.com/dcramer/django-idmapper.git\n\nEvery document (forum message) forms two overlaying networks of nodes\nthat has a copy of that document. The networks are connected graphs,\nand one of them is a strict subnetwork of the other one. The smaller\none is the \"subscribing\" set. Nodes in the subscribing set gets copies\nof all comments to the document. The protocol is push-based: When you\nhave a peer that is subscribed to a document you have, and you have a\ncomment to that document, you send that comment to the peer. The\nprotocol attempts to keep the network for a document a connected graph\nby allways electing a \"root node\" among themselves, and keeping track\nof their distances from that root node. This way, no closed,\ndisconnected circles can form (circles can still form, bur they'r\nobvious). This means that a document is only present on the nodes\nactually interested in that particular document. It is a bit like what\nNNTP would be, where nodes subscribe to newsgroups, if every message\nhad its own newsgroup.\n\nNode A only pushes comments to document x to B if A and B share\ndocument x. Every node should probably have a max-peers-per-document\nsetting to keep the branching level reasonable. For two nodes to\ninitiate contact, they both need to know a third node, and share the\nsame document with that third node. For eaxmple a \"root document\"\n\nEvery \"virtual forum\" consist of a root document, and you have to have\nits id, and the address of a peer that also has it, to initiate\ncontact / usage of that forum. Every document (forum message) linked\nfrom teh root, or from documents linked from the root (and so on)\nforms its own network, and the original peer with the root document\nneed not be part of every such network.\n\nYou install i2p and cliqueclique on your machine, then go to\nlocalhost:whatever in your browser. You enter a peer address and forum\nroot document id You _can_ of course run a node publicly as a website\ntoo\n\nMy current django code supports multiple nodes in one installation,\neach node connected to a django user object It's a rather simple idea\nreally. Only drawback I can think of is overhead :S\n\n\n# Algorithms\n\n## Metadata sync\n\n\n### Node1 (server)\n    Data:\n     local: Its own data\n     serial: Version of its data\n     serialcopy: copy of the other nodes' copy of its own serial\n     time=1\n\n    When local changes:\n      serial += 1\n      time = 1\n\n    While serial != serialcopy:\n      Send (local, serial) to other node\n      Wait time\n      time *= 2\n\n    When receiving:\n      if received.serial == serial:\n        serialcopy = serial\n     \n\n### Node2 (client)\n    Data\n      peer: a copy of the other nodes' data\n      peerserial: copy of the other nodes' serial\n\n    When receiving:\n      Copy received.local to peer\n      Send received.serial back to other node\n\n\n\n## Metadata deletion\n\n\n### Node1 (server)\n    Data:\n     local: Its own data\n\n    While local exists:\n     Send delete request to other node\n\n    When receiving:\n     Delete local\n\n\n### Node2 (client)\n    Data\n      peer: a copy of the other nodes' data\n\n    When receiving:\n     Delete peer\n     Send ACK to peer\n\n\n## Stuff built on top of this protocol\n\n### Directory\n\nA directory is a set of documents that can not (directly) be listed\nbut that can be searched by prefix and matches can be listed. It is\nintended for large collections of documents.\n\n#### Basic idea\n\nA tree structure where each node represents one more character in the\nsubject of (a set of) content document(s). The leaves are the content\ndocuments. Thus any path down the tree represents a prefix of the\nsubject.\n\n\n\n# Document formats\n## Content document\n\n    {\"__smime_MIMESigned__\": true,\n     \"header\": {},\n     \"parts\": [{\"__email_mime_multipart_MIMEMultipart__\": true,\n                \"parts\": [{\"__email_message_Message__\": true,\n                           \"body\": \"\",\n                           \"header\": {\"part_type\": \"content\",\n                                      \"Content-Type\": \"text/plain; charset=\\\"utf-8\\\"\"}}],\n                \"header\": {}}]}\n\n\n## Links\n\n    {\"__smime_MIMESigned__\": true,\n     \"header\": {},\n     \"parts\": [{\"__email_mime_multipart_MIMEMultipart__\": true,\n                \"parts\": [{\"__email_message_Message__\": true,\n                           \"body\": \"\",\n                           \"header\": {\"part_type\": \"link\",\n                                      \"link_direction\": \"reversed\"|\"natural\",\n                                      \"Content-Type\": \"text/plain; charset=\\\"utf-8\\\"\"}}],\n                \"header\": {\"parent_document_id\": \"\",\n                           \"child_document_id\": \"\",\n                           \"subject\": \"\"}}]},\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fredhog%2Fcliqueclique","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fredhog%2Fcliqueclique","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fredhog%2Fcliqueclique/lists"}