12 | {state === 'connected' && ( 13 | {'\u{2705}'} connected 14 | )} 15 | {state === 'connecting' && ( 16 | {'\u{23f3}'} connecting 17 | )} 18 | {state === 'disconnected' && ( 19 | {'\u{274c}'} disconnected 20 | )} 21 |
22 | ); 23 | } 24 | -------------------------------------------------------------------------------- /apps/WeBox/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webox-app", 3 | "version": "0.0.1", 4 | "description": "Distributed P2P Git Hosting Provider Network", 5 | "main": "index.jsx", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": { 10 | "name": "Dmitry Yakimov", 11 | "url": "http://welldan97.com" 12 | }, 13 | "keywords": [ 14 | "WeGit", 15 | "p2p", 16 | "peer", 17 | "webrtc", 18 | "git", 19 | "git hosting", 20 | "network" 21 | ], 22 | "repository": { 23 | "type": "git", 24 | "url": "git://github.com/welldan97/WeGit.git" 25 | }, 26 | "bugs": { 27 | "url": "https://github.com/welldan97/WeGit/issues" 28 | }, 29 | "homepage": "https://github.com/welldan97/WeGit", 30 | "license": "MIT" 31 | } -------------------------------------------------------------------------------- /apps/WeWeWeChat/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wewewechat-app", 3 | "version": "0.0.1", 4 | "description": "Distributed P2P Git Hosting Provider Network", 5 | "main": "index.jsx", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": { 10 | "name": "Dmitry Yakimov", 11 | "url": "http://welldan97.com" 12 | }, 13 | "keywords": [ 14 | "WeGit", 15 | "p2p", 16 | "peer", 17 | "webrtc", 18 | "git", 19 | "git hosting", 20 | "network" 21 | ], 22 | "repository": { 23 | "type": "git", 24 | "url": "git://github.com/welldan97/WeGit.git" 25 | }, 26 | "bugs": { 27 | "url": "https://github.com/welldan97/WeGit/issues" 28 | }, 29 | "homepage": "https://github.com/welldan97/WeGit", 30 | "license": "MIT" 31 | } -------------------------------------------------------------------------------- /browser-client/scripts/build: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | export NODE_ENV=production; 6 | 7 | # build wegit app 8 | ( 9 | cd ../apps/WeGit 10 | rm -rf ./dist 11 | npx parcel build --no-source-maps --no-content-hash index.jsx 12 | head -n 7 < index.jsx | cat - ./dist/index.js > ./dist/next.js && mv ./dist/next.js ./dist/index.js 13 | ) 14 | 15 | #rm -rf .cache 16 | rm -rf ./dist 17 | # NOTE: build:appShell is needed for development 18 | npm run build:appShell 19 | # NOTE: build:appShell creates some dev file, remove it 20 | rm ./dist/dev.*.js 21 | 22 | parcel build --no-source-maps --no-content-hash entries/index.js 23 | 24 | { 25 | head -n 1 < ./entries/index.html 26 | echo '' 29 | } > ./dist/index.html 30 | cp ./public/* dist 31 | -------------------------------------------------------------------------------- /lib/utils/parseAppSource.js: -------------------------------------------------------------------------------- 1 | // Imports 2 | // ============================================================================= 3 | 4 | const nanoid = require('nanoid'); 5 | 6 | // Main 7 | // ============================================================================= 8 | 9 | module.exports = (appSource, options) => { 10 | const { groups: rawApp } = new RegExp( 11 | `// ==WgApp== 12 | // @id (?
21 | {previewFile.contents}
22 |
23 | )}
24 | {isMarkdown && ${JSON.stringify(meshState, undefined, 2)}`);
50 | });
51 |
52 | app.delete('/', (req, res) => reset());
53 |
54 | app.post('/', async (req, res) => {
55 | const { wgOffer } = req.body;
56 | const { wgAnswer } = await wgOs.join(wgOffer);
57 | if (wgAnswer) return res.json({ wgAnswer });
58 | res.status(409);
59 | res.send();
60 | });
61 |
62 | app.listen(port, () => console.log(`Listening on port ${port}!`));
63 |
--------------------------------------------------------------------------------
/browser-client/config/index.js:
--------------------------------------------------------------------------------
1 | // Imports
2 | // =============================================================================
3 |
4 | import parseAppSource from 'wegit-lib/utils/parseAppSource';
5 |
6 | import { readFileSync, existsSync } from 'fs';
7 |
8 | const WeWeWeChatSource = readFileSync(
9 | __dirname + '../../../apps/WeWeWeChat/index.jsx',
10 | 'utf-8',
11 | );
12 |
13 | const WeBoxSource = readFileSync(
14 | __dirname + '../../../apps/WeBox/index.jsx',
15 | 'utf-8',
16 | );
17 |
18 | const WeGitSource = readFileSync(
19 | //__dirname + '../../../apps/WeGit/index.jsx',
20 | __dirname + '../../../apps/WeGit/dist/index.js',
21 | 'utf-8',
22 | );
23 |
24 | let baseConfig = {};
25 |
26 | if (process.env.NODE_ENV === 'development')
27 | baseConfig = JSON.parse(
28 | readFileSync(__dirname + '../../../config.json', 'utf-8'),
29 | );
30 |
31 | // Utils
32 | // =============================================================================
33 |
34 | const isFile = () => window.location.protocol === 'file:';
35 |
36 | // Main
37 | // =============================================================================
38 | export default () => ({
39 | tab: 'network',
40 | iceServers: [{ urls: ['stun:stun.l.google.com:19302'] }],
41 | signalling: undefined,
42 | //runApp: 'WE-WE-WE-WE-WE-WECHAT',
43 | runApp: false,
44 | iframeMode: {
45 | // NOTE: crossOrigin doesn't work yet
46 | type: 'sameOrigin',
47 | },
48 | serviceWorkers: !isFile(),
49 | appShellLocalApp: false,
50 | alwaysDefaultConfig: false,
51 | ...baseConfig,
52 | initialApps: [
53 | parseAppSource(WeWeWeChatSource),
54 | parseAppSource(WeBoxSource),
55 | parseAppSource(WeGitSource),
56 | ...(baseConfig.initialApps || []),
57 | ],
58 | });
59 |
--------------------------------------------------------------------------------
/lib/utils/receiveInChunksMiddleware.js:
--------------------------------------------------------------------------------
1 | // Imports
2 | // =============================================================================
3 |
4 | const nanoid = require('nanoid');
5 |
6 | // Main
7 | // =============================================================================
8 |
9 | const MAX_SIZE = 10000;
10 |
11 | module.exports = ({ send, onMessage, ...args }) => {
12 | const receivedChunks = {};
13 |
14 | const receiveChunk = (message, { onProgress = () => {}, ...options }) => {
15 | const {
16 | path: [userId],
17 | payload: { id, chunkBody, chunkNo, chunksCount },
18 | } = message;
19 | if (!receivedChunks[id]) receivedChunks[id] = '';
20 | receivedChunks[id] += chunkBody;
21 | onProgress({
22 | phase: 'Receiving',
23 | loaded: chunkNo,
24 | total: chunksCount - 1,
25 | lengthComputable: true,
26 | });
27 |
28 | if (chunkNo !== chunksCount - 1)
29 | send(userId, { type: 'nextChunk', payload: { id } });
30 | else {
31 | const parsedMessage = JSON.parse(receivedChunks[id]);
32 | onMessage({ ...message, ...parsedMessage }, options);
33 | delete receivedChunks[id];
34 | }
35 | };
36 |
37 | //----------------------------------------------------------------------------
38 |
39 | const nextSend = (userId, message, options = {}) => {
40 | if (message.type === 'chunks') return; // TODO
41 | if (message.type === 'nextChunk') return; // TODO
42 | return send(userId, message, options);
43 | };
44 |
45 | const nextOnMessage = (message, options = {}) => {
46 | if (message.type === 'chunks') return receiveChunk(message, options);
47 | else return onMessage(message, options);
48 | };
49 |
50 | return { ...args, send: nextSend, onMessage: nextOnMessage };
51 | };
52 |
--------------------------------------------------------------------------------
/browser-client/components/NetworkTab/Tabs.jsx:
--------------------------------------------------------------------------------
1 | // Imports
2 | // =============================================================================
3 |
4 | import React from 'react';
5 |
6 | // Main
7 | // =============================================================================
8 |
9 | export default function Tabs({
10 | active,
11 | onActivate,
12 | connectingPeersCount,
13 | connectedPeersCount,
14 | }) {
15 | return (
16 | {pullRequest.comment}
28 | 29 |60 | {a.description} 61 |
62 |
108 | {showInnerState &&
109 | JSON.stringify(
110 | innerState,
111 | (key, value) => (typeof value === 'undefined' ? null : value),
112 | 2,
113 | )}
114 |
115 | {JSON.stringify(state, undefined, 2)}
117 | | 59 | { 62 | e.preventDefault(); 63 | onPathChange(path.replace(/\/[^/]*$/, '') || '/'); 64 | }} 65 | style={{ 66 | textDecoration: 'none', 67 | }} 68 | > 69 | {'\u{1F4C1}'} 70 | .. 71 | 72 | | 73 |74 | | 75 | |
|---|---|---|
| 87 | { 90 | e.preventDefault(); 91 | onPathChange(`${path === '/' ? '' : path}/${f.name}`); 92 | }} 93 | style={{ 94 | textDecoration: 'none', 95 | }} 96 | > 97 | {f.isDirectory ? '\u{1F4C1} ' : '\u{1F4C4} '} 98 | {f.name} 99 | 100 | | 101 |102 | {formatCommitMessage(f.commitHolder)} 103 | | 104 |108 | {formatCommitDate(f.commitHolder)} 109 | | 110 |
100 | {testsState === 'success' && ( 101 | 102 | {'\u{2705}'} tests are passing 103 | 104 | )} 105 | {testsState === 'fail' && ( 106 | 107 | {'\u{274C}'} tests are failing 108 | 109 | )} 110 | {testsState === 'disabled' && '\u{00a0}'} 111 |
112 |Choose a way to get started:
38 |49 | Just fill in the url, and the repository would be cloned 50 | from there, and will appear here 51 |
52 | 77 |89 | You can do it via command line interface. 90 |
91 |92 | First you need to install git remote helper: 93 |
94 |npm install git-remote-wegit --global95 |
Then run the wegit Node.js bridge
96 |npx wegit-node-bridge97 |
98 | Make sure you got connected to the browser application.
99 |
100 | And finally add remote and push:
101 |
103 | git remote add origin wegit://example106 |
104 | git push -u origin master 105 |
Thank you for trying out WeGit! I hope you liked it :)
37 |38 | Note that we are still in a proof of concept stage of development, 39 | and many things are going to break in many different funny ways. 40 |
41 |42 | Nevertheless, the work will be going on, and we are going to make it 43 | solid. Please support the project: 44 |
45 |Thanks!
56 |64 | Thanks to the opensource projects, without which this project would 65 | not be possible: 66 |
67 |93 | Thanks to{' '} 94 | logo-o-matic{' '} 95 | for generated logo, using font created by Di-Art. 96 |
97 |98 | Thanks to Chiptune Planet{' '} 99 | for making the music which I used on this page. 100 |
101 |102 | Thanks to{' '} 103 | Z-Exit for 104 | the translated lyrics of the song originally written by Viktor Tsoi 105 |
106 |
113 | {`
114 | Copyright (c) 2020 Dmitry Yakimov (welldan97)
115 | Permission is hereby granted, free of charge, to any person obtaining a copy
116 | of this software and associated documentation files (the "Software"), to deal
117 | in the Software without restriction, including without limitation the rights
118 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
119 | copies of the Software, and to permit persons to whom the Software is
120 | furnished to do so, subject to the following conditions:
121 |
122 | The above copyright notice and this permission notice shall be included in all
123 | copies or substantial portions of the Software.
124 |
125 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
126 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
127 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
128 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
129 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
130 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
131 | SOFTWARE.
132 | `}
133 |
134 |