├── .hound.yml ├── examples ├── socket-channel │ ├── .gitignore │ ├── server.js │ ├── package.json │ ├── remote.js │ ├── local.js │ ├── index.html │ └── yarn.lock ├── data-channel │ ├── server.js │ ├── package.json │ ├── remote.js │ ├── local.js │ ├── index.html │ └── yarn.lock └── local-connection │ ├── server.js │ ├── package.json │ ├── remote.js │ ├── local.js │ ├── index.html │ └── yarn.lock ├── src ├── app │ ├── EventHandler.ts │ ├── EventHandlerCollection.ts │ ├── __tests__ │ │ ├── App.test.ts │ │ └── Dispatcher.test.ts │ ├── Configuration.ts │ ├── EventDispatcher.ts │ ├── Signaling.ts │ ├── SocketChannel.ts │ ├── App.ts │ ├── Room.ts │ └── Participant.ts └── index.ts ├── website ├── src │ ├── static │ │ ├── img │ │ │ ├── logo.png │ │ │ └── webrtc.png │ │ ├── favicon │ │ │ ├── favicon.ico │ │ │ ├── apple-icon.png │ │ │ ├── favicon-16x16.png │ │ │ ├── favicon-32x32.png │ │ │ ├── favicon-96x96.png │ │ │ ├── ms-icon-70x70.png │ │ │ ├── apple-icon-57x57.png │ │ │ ├── apple-icon-60x60.png │ │ │ ├── apple-icon-72x72.png │ │ │ ├── apple-icon-76x76.png │ │ │ ├── ms-icon-144x144.png │ │ │ ├── ms-icon-150x150.png │ │ │ ├── ms-icon-310x310.png │ │ │ ├── android-icon-36x36.png │ │ │ ├── android-icon-48x48.png │ │ │ ├── android-icon-72x72.png │ │ │ ├── android-icon-96x96.png │ │ │ ├── apple-icon-114x114.png │ │ │ ├── apple-icon-120x120.png │ │ │ ├── apple-icon-144x144.png │ │ │ ├── apple-icon-152x152.png │ │ │ ├── apple-icon-180x180.png │ │ │ ├── android-icon-144x144.png │ │ │ ├── android-icon-192x192.png │ │ │ └── apple-icon-precomposed.png │ │ ├── browserconfig.xml │ │ ├── css │ │ │ └── custom.css │ │ └── manifest.json │ ├── .gitignore │ ├── sidebars.json │ ├── package.json │ ├── pages │ │ └── en │ │ │ ├── users.js │ │ │ ├── help.js │ │ │ └── index.js │ ├── core │ │ └── Footer.js │ ├── siteConfig.js │ └── README.md └── docs │ ├── error.md │ ├── data.md │ ├── socket.md │ ├── local.md │ ├── data-channel.md │ ├── installation.md │ ├── client.md │ ├── media-stream.md │ └── signaling.md ├── tsconfig.test.json ├── .npmignore ├── .gitignore ├── .editorconfig ├── .travis.yml ├── .yarnclean ├── .github ├── FUNDING.yml ├── workflows │ └── website-publish.yml ├── CONTRIBUTING.md └── CODE_OF_CONDUCT.md ├── tsconfig.json ├── rollup.config.js ├── LICENSE ├── package.json ├── README.md └── .eslintrc.js /.hound.yml: -------------------------------------------------------------------------------- 1 | eslint: 2 | enabled: true 3 | config_file: .eslintrc -------------------------------------------------------------------------------- /examples/socket-channel/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.log 3 | node_modules -------------------------------------------------------------------------------- /src/app/EventHandler.ts: -------------------------------------------------------------------------------- 1 | export type EventHandler = (...args: any[]) => any; 2 | -------------------------------------------------------------------------------- /website/src/static/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vardius/peer-data/HEAD/website/src/static/img/logo.png -------------------------------------------------------------------------------- /website/src/static/img/webrtc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vardius/peer-data/HEAD/website/src/static/img/webrtc.png -------------------------------------------------------------------------------- /website/src/static/favicon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vardius/peer-data/HEAD/website/src/static/favicon/favicon.ico -------------------------------------------------------------------------------- /website/src/static/favicon/apple-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vardius/peer-data/HEAD/website/src/static/favicon/apple-icon.png -------------------------------------------------------------------------------- /tsconfig.test.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /website/src/static/favicon/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vardius/peer-data/HEAD/website/src/static/favicon/favicon-16x16.png -------------------------------------------------------------------------------- /website/src/static/favicon/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vardius/peer-data/HEAD/website/src/static/favicon/favicon-32x32.png -------------------------------------------------------------------------------- /website/src/static/favicon/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vardius/peer-data/HEAD/website/src/static/favicon/favicon-96x96.png -------------------------------------------------------------------------------- /website/src/static/favicon/ms-icon-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vardius/peer-data/HEAD/website/src/static/favicon/ms-icon-70x70.png -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .code 3 | .rpt2_cache 4 | .DS_Store 5 | *.log 6 | node_modules 7 | coverage 8 | src 9 | test 10 | npm-debug.log 11 | -------------------------------------------------------------------------------- /website/src/static/favicon/apple-icon-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vardius/peer-data/HEAD/website/src/static/favicon/apple-icon-57x57.png -------------------------------------------------------------------------------- /website/src/static/favicon/apple-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vardius/peer-data/HEAD/website/src/static/favicon/apple-icon-60x60.png -------------------------------------------------------------------------------- /website/src/static/favicon/apple-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vardius/peer-data/HEAD/website/src/static/favicon/apple-icon-72x72.png -------------------------------------------------------------------------------- /website/src/static/favicon/apple-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vardius/peer-data/HEAD/website/src/static/favicon/apple-icon-76x76.png -------------------------------------------------------------------------------- /website/src/static/favicon/ms-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vardius/peer-data/HEAD/website/src/static/favicon/ms-icon-144x144.png -------------------------------------------------------------------------------- /website/src/static/favicon/ms-icon-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vardius/peer-data/HEAD/website/src/static/favicon/ms-icon-150x150.png -------------------------------------------------------------------------------- /website/src/static/favicon/ms-icon-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vardius/peer-data/HEAD/website/src/static/favicon/ms-icon-310x310.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | typings 2 | .code 3 | .rpt2_cache 4 | .DS_Store 5 | *.log 6 | node_modules 7 | dist 8 | coverage 9 | .idea 10 | npm-debug.log 11 | -------------------------------------------------------------------------------- /website/src/static/favicon/android-icon-36x36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vardius/peer-data/HEAD/website/src/static/favicon/android-icon-36x36.png -------------------------------------------------------------------------------- /website/src/static/favicon/android-icon-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vardius/peer-data/HEAD/website/src/static/favicon/android-icon-48x48.png -------------------------------------------------------------------------------- /website/src/static/favicon/android-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vardius/peer-data/HEAD/website/src/static/favicon/android-icon-72x72.png -------------------------------------------------------------------------------- /website/src/static/favicon/android-icon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vardius/peer-data/HEAD/website/src/static/favicon/android-icon-96x96.png -------------------------------------------------------------------------------- /website/src/static/favicon/apple-icon-114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vardius/peer-data/HEAD/website/src/static/favicon/apple-icon-114x114.png -------------------------------------------------------------------------------- /website/src/static/favicon/apple-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vardius/peer-data/HEAD/website/src/static/favicon/apple-icon-120x120.png -------------------------------------------------------------------------------- /website/src/static/favicon/apple-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vardius/peer-data/HEAD/website/src/static/favicon/apple-icon-144x144.png -------------------------------------------------------------------------------- /website/src/static/favicon/apple-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vardius/peer-data/HEAD/website/src/static/favicon/apple-icon-152x152.png -------------------------------------------------------------------------------- /website/src/static/favicon/apple-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vardius/peer-data/HEAD/website/src/static/favicon/apple-icon-180x180.png -------------------------------------------------------------------------------- /website/src/static/favicon/android-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vardius/peer-data/HEAD/website/src/static/favicon/android-icon-144x144.png -------------------------------------------------------------------------------- /website/src/static/favicon/android-icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vardius/peer-data/HEAD/website/src/static/favicon/android-icon-192x192.png -------------------------------------------------------------------------------- /website/src/static/favicon/apple-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vardius/peer-data/HEAD/website/src/static/favicon/apple-icon-precomposed.png -------------------------------------------------------------------------------- /src/app/EventHandlerCollection.ts: -------------------------------------------------------------------------------- 1 | import { EventHandler } from './EventHandler'; 2 | 3 | export interface EventHandlerCollection { 4 | [type: string]: EventHandler[]; 5 | } 6 | -------------------------------------------------------------------------------- /website/src/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | node_modules 4 | build 5 | 6 | lib/core/metadata.js 7 | lib/core/MetadataBlog.js 8 | 9 | /translated_docs 10 | /build/ 11 | /node_modules 12 | /i18n/* 13 | 14 | yarn.lock 15 | -------------------------------------------------------------------------------- /website/src/sidebars.json: -------------------------------------------------------------------------------- 1 | { 2 | "docs": { 3 | "Quick Start": ["installation", "client", "signaling"], 4 | "Connection": ["data-channel", "media-stream"], 5 | "Examples": ["error", "local", "socket", "data"] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | indent_style = space 11 | indent_size = 2 -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "stable" 4 | script: 5 | - yarn test:cov && codecov 6 | before_install: 7 | - npm install -g yarn 8 | - npm i -g codecov 9 | after_success: 10 | - bash <(curl -s https://codecov.io/bash) -e TRAVIS_NODE_VERSION 11 | -------------------------------------------------------------------------------- /website/src/static/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | #ffffff -------------------------------------------------------------------------------- /website/src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "examples": "docusaurus-examples", 4 | "start": "docusaurus-start", 5 | "build": "docusaurus-build", 6 | "publish-gh-pages": "docusaurus-publish", 7 | "write-translations": "docusaurus-write-translations", 8 | "version": "docusaurus-version", 9 | "rename-version": "docusaurus-rename-version" 10 | }, 11 | "devDependencies": { 12 | "docusaurus": "^1.14.4" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/app/__tests__/App.test.ts: -------------------------------------------------------------------------------- 1 | import { App } from '../App'; 2 | import { EventDispatcher } from '../EventDispatcher'; 3 | 4 | const servers = { 5 | iceServers: [ 6 | { urls: ['stun:stun.1.google.com:19302'] }, 7 | ], 8 | }; 9 | const constraints = { ordered: true }; 10 | const dispatcher =new EventDispatcher(); 11 | 12 | const app = new App(dispatcher, servers, constraints); 13 | 14 | test('App init', (): void => { 15 | expect(app).toBeDefined(); 16 | }); 17 | -------------------------------------------------------------------------------- /src/app/Configuration.ts: -------------------------------------------------------------------------------- 1 | export class Configuration { 2 | private servers: RTCConfiguration = {}; 3 | private dataConstraints?: RTCDataChannelInit; 4 | 5 | setServers = (servers: RTCConfiguration): void => { 6 | this.servers = servers; 7 | }; 8 | 9 | getServers = (): RTCConfiguration => this.servers; 10 | 11 | setDataConstraints = (dataConstraints: RTCDataChannelInit): void => { 12 | this.dataConstraints = dataConstraints; 13 | }; 14 | 15 | getDataConstraints = (): RTCDataChannelInit | undefined => this.dataConstraints; 16 | } 17 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | // import 'webrtc-adapter'; 2 | 3 | import { App as PeerData } from './app/App'; 4 | 5 | import { Room } from './app/Room'; 6 | import { Participant } from './app/Participant'; 7 | import { EventDispatcher } from './app/EventDispatcher'; 8 | 9 | import { Signaling, SignalingEvent, SignalingEventType } from './app/Signaling'; 10 | import { SocketChannel } from './app/SocketChannel'; 11 | 12 | export { 13 | Room, 14 | Participant, 15 | EventDispatcher, 16 | Signaling, 17 | SignalingEvent, 18 | SignalingEventType, 19 | SocketChannel, 20 | }; 21 | 22 | export default PeerData; 23 | -------------------------------------------------------------------------------- /.yarnclean: -------------------------------------------------------------------------------- 1 | # test directories 2 | __tests__ 3 | # test 4 | tests 5 | powered-test 6 | .code 7 | .rpt2_cache 8 | 9 | # asset directories 10 | docs 11 | doc 12 | website 13 | images 14 | assets 15 | 16 | # examples 17 | example 18 | examples 19 | 20 | # code coverage directories 21 | coverage 22 | .nyc_output 23 | 24 | # build scripts 25 | Makefile 26 | Gulpfile.js 27 | Gruntfile.js 28 | 29 | # configs 30 | .tern-project 31 | .gitattributes 32 | .editorconfig 33 | .*ignore 34 | .eslintrc 35 | .jshintrc 36 | .flowconfig 37 | .documentup.json 38 | .yarn-metadata.json 39 | .*.yml 40 | *.yml 41 | 42 | # misc 43 | *.gz 44 | *.md 45 | -------------------------------------------------------------------------------- /website/src/static/css/custom.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | /* your custom css */ 9 | 10 | @media only screen and (min-device-width: 360px) and (max-device-width: 736px) { 11 | } 12 | 13 | @media only screen and (min-width: 1024px) { 14 | } 15 | 16 | @media only screen and (max-width: 1023px) { 17 | } 18 | 19 | @media only screen and (min-width: 1400px) { 20 | } 21 | 22 | @media only screen and (min-width: 1500px) { 23 | } 24 | 25 | .codeSample { 26 | text-align: initial !important; 27 | } 28 | -------------------------------------------------------------------------------- /examples/data-channel/server.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const fspath = require("path"); 3 | const http = require("http"); 4 | const fs = require("fs"); 5 | 6 | const port = process.env.PORT || 3000; 7 | 8 | const app = express(); 9 | app.get("/local.js", (req, res) => res.sendFile(fspath.join(__dirname, "local.js"))); 10 | app.get("/remote.js", (req, res) => res.sendFile(fspath.join(__dirname, "remote.js"))); 11 | app.get("/favicon.ico", (req, res) => res.sendStatus(404)); 12 | app.get("*", (req, res) => res.sendFile(fspath.join(__dirname, "index.html"))); 13 | 14 | const server = http.createServer(app); 15 | 16 | server.listen(port, () => console.log(`Server started at port ${port}`)); 17 | -------------------------------------------------------------------------------- /examples/local-connection/server.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const fspath = require("path"); 3 | const http = require("http"); 4 | const fs = require("fs"); 5 | 6 | const port = process.env.PORT || 3000; 7 | 8 | const app = express(); 9 | app.get("/local.js", (req, res) => res.sendFile(fspath.join(__dirname, "local.js"))); 10 | app.get("/remote.js", (req, res) => res.sendFile(fspath.join(__dirname, "remote.js"))); 11 | app.get("/favicon.ico", (req, res) => res.sendStatus(404)); 12 | app.get("*", (req, res) => res.sendFile(fspath.join(__dirname, "index.html"))); 13 | 14 | const server = http.createServer(app); 15 | 16 | server.listen(port, () => console.log(`Server started at port ${port}`)); 17 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [vardius] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with a single custom sponsorship URL 13 | -------------------------------------------------------------------------------- /examples/data-channel/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "peer-data-example", 3 | "version": "1.0.0", 4 | "description": "Peer-Data socket data channel example", 5 | "main": "index.html", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node server.js" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/vardius/peer-data.git" 13 | }, 14 | "keywords": [ 15 | "peer-data", 16 | "webrtc" 17 | ], 18 | "author": { 19 | "name": "Rafał Lorenz", 20 | "email": "vardius@gmail.com" 21 | }, 22 | "license": "MIT", 23 | "bugs": { 24 | "url": "https://github.com/vardius/peer-data/issues" 25 | }, 26 | "homepage": "https://github.com/vardius/peer-data#readme", 27 | "dependencies": { 28 | "express": "^4.15.3" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /examples/local-connection/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "peer-data-example", 3 | "version": "1.0.0", 4 | "description": "Peer-Data socket local connection example", 5 | "main": "index.html", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node server.js" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/vardius/peer-data.git" 13 | }, 14 | "keywords": [ 15 | "peer-data", 16 | "webrtc" 17 | ], 18 | "author": { 19 | "name": "Rafał Lorenz", 20 | "email": "vardius@gmail.com" 21 | }, 22 | "license": "MIT", 23 | "bugs": { 24 | "url": "https://github.com/vardius/peer-data/issues" 25 | }, 26 | "homepage": "https://github.com/vardius/peer-data#readme", 27 | "dependencies": { 28 | "express": "^4.15.3" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /examples/socket-channel/server.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const fspath = require("path"); 3 | const http = require("http"); 4 | const fs = require("fs"); 5 | const PeerDataServer = require("peer-data-server"); 6 | 7 | const port = process.env.PORT || 3000; 8 | 9 | const app = express(); 10 | app.get("/local.js", (req, res) => res.sendFile(fspath.join(__dirname, "local.js"))); 11 | app.get("/remote.js", (req, res) => res.sendFile(fspath.join(__dirname, "remote.js"))); 12 | app.get("/favicon.ico", (req, res) => res.sendStatus(404)); 13 | app.get("*", (req, res) => res.sendFile(fspath.join(__dirname, "index.html"))); 14 | 15 | const appendPeerDataServer = PeerDataServer.default || PeerDataServer; 16 | const server = http.createServer(app); 17 | 18 | appendPeerDataServer(server); 19 | 20 | server.listen(port, () => console.log(`Server started at port ${port}`)); 21 | -------------------------------------------------------------------------------- /website/docs/error.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: error 3 | title: Error Handling 4 | sidebar_label: Error Handling 5 | --- 6 | 7 | ## Example 8 | 9 | ```javascript 10 | const room = peerData.connect('test-room'); 11 | 12 | room 13 | // you can catch errors here to know if the peer connection init failed 14 | .on("error", event => console.log(event)); 15 | .on("participant", participant => { 16 | //here you can catch errors for ice candidates negotiation 17 | //and setting remote description (only for getting an answer) 18 | //remote description errors provided by offer are thrown by promise 19 | participant.on("error", event => { 20 | console.log("error", event); 21 | 22 | // You can renegotiate connection with peer by calling 23 | participant.renegotiate(); 24 | }) 25 | }); 26 | ``` 27 | -------------------------------------------------------------------------------- /examples/socket-channel/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "peer-data-example", 3 | "version": "1.0.0", 4 | "description": "Peer-Data socket signalling example", 5 | "main": "index.html", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node server.js" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/vardius/peer-data.git" 13 | }, 14 | "keywords": [ 15 | "peer-data", 16 | "webrtc" 17 | ], 18 | "author": { 19 | "name": "Rafał Lorenz", 20 | "email": "vardius@gmail.com" 21 | }, 22 | "license": "MIT", 23 | "bugs": { 24 | "url": "https://github.com/vardius/peer-data/issues" 25 | }, 26 | "homepage": "https://github.com/vardius/peer-data#readme", 27 | "dependencies": { 28 | "express": "^4.15.3", 29 | "peer-data": "^3.2.2", 30 | "peer-data-server": "^1.0.10", 31 | "socket.io": "^2.4.0" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /website/docs/data.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: data 3 | title: Data channel example 4 | sidebar_label: Data channel example 5 | --- 6 | 7 | ## Example 8 | 9 | In the repository root directory you can find some simple examples. Click [here for data channel example](https://github.com/vardius/peer-data/tree/master/examples/data-channel). 10 | 11 | This simple project demonstrates how to setup WebRTC connection using [peer-data](https://github.com/vardius/peer-data) with data channel. 12 | 13 | To run this example simple clone the repository and perform the following from the root directory: 14 | 15 | ```sh 16 | ➜ examples git:(master) ✗ cd data-channel 17 | ➜ data-channel git:(master) ✗ yarn 18 | [1/4] 🔍 Resolving packages... 19 | success Already up-to-date. 20 | ✨ Done in 0.13s. 21 | ➜ data-channel git:(master) ✗ yarn start 22 | $ node server.js 23 | Server started at port 3000 24 | ``` 25 | 26 | Then open [http://localhost:3000/](http://localhost:3000/). 27 | -------------------------------------------------------------------------------- /.github/workflows/website-publish.yml: -------------------------------------------------------------------------------- 1 | 2 | name: Publish website to GitHub Pages 3 | on: 4 | # Trigger the workflow on push or pull request, 5 | # but only for the master branch 6 | push: 7 | branches: 8 | - master 9 | pull_request: 10 | branches: 11 | - master 12 | jobs: 13 | publish: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Copy Files 17 | uses: actions/checkout@v2 18 | - name: Setup Git 19 | run: | 20 | git config --global user.name "$GITHUB_ACTOR" 21 | git config --global user.email "$GITHUB_ACTOR@users.noreply.github.com" 22 | - name: install 23 | run: cd website/src && yarn install 24 | - name: build 25 | run: cd website/src && yarn build 26 | - name: Publish website 27 | env: 28 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 29 | run: cd website/src && GIT_USER="$GITHUB_ACTOR:$GITHUB_TOKEN" CURRENT_BRANCH=master yarn run publish-gh-pages 30 | -------------------------------------------------------------------------------- /website/src/static/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "peer-data", 3 | "icons": [ 4 | { 5 | "src": "\/favicon\/android-icon-36x36.png", 6 | "sizes": "36x36", 7 | "type": "image\/png", 8 | "density": "0.75" 9 | }, 10 | { 11 | "src": "\/favicon\/android-icon-48x48.png", 12 | "sizes": "48x48", 13 | "type": "image\/png", 14 | "density": "1.0" 15 | }, 16 | { 17 | "src": "\/favicon\/android-icon-72x72.png", 18 | "sizes": "72x72", 19 | "type": "image\/png", 20 | "density": "1.5" 21 | }, 22 | { 23 | "src": "\/favicon\/android-icon-96x96.png", 24 | "sizes": "96x96", 25 | "type": "image\/png", 26 | "density": "2.0" 27 | }, 28 | { 29 | "src": "\/favicon\/android-icon-144x144.png", 30 | "sizes": "144x144", 31 | "type": "image\/png", 32 | "density": "3.0" 33 | }, 34 | { 35 | "src": "\/favicon\/android-icon-192x192.png", 36 | "sizes": "192x192", 37 | "type": "image\/png", 38 | "density": "4.0" 39 | } 40 | ] 41 | } -------------------------------------------------------------------------------- /src/app/EventDispatcher.ts: -------------------------------------------------------------------------------- 1 | import { EventHandlerCollection } from './EventHandlerCollection'; 2 | import { EventHandler } from './EventHandler'; 3 | 4 | export class EventDispatcher { 5 | private handlers: EventHandlerCollection = {}; 6 | 7 | register = (type: string, callback: EventHandler): void => { 8 | if (!this.handlers[type]) { 9 | this.handlers[type] = []; 10 | } 11 | this.handlers[type].push(callback); 12 | }; 13 | 14 | unregister = (type: string, callback: EventHandler): void => { 15 | if (this.handlers[type]) { 16 | const index = this.handlers[type].indexOf(callback); 17 | if (index !== -1) { 18 | delete this.handlers[type][index]; 19 | } 20 | } 21 | }; 22 | 23 | dispatch = (type: string, ...args: any[]): void => { 24 | if (this.handlers[type]) { 25 | this.handlers[type].forEach(h => h(...args)); 26 | } 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /website/docs/socket.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: socket 3 | title: Socket signalling channel 4 | sidebar_label: Socket signalling channel 5 | --- 6 | 7 | ## Example 8 | 9 | In the repository root directory you can find some simple examples. Click [here for socket signalling channel example](https://github.com/vardius/peer-data/tree/master/examples/socket-channel). 10 | 11 | This simple project demonstrates how to setup WebRTC connection using [peer-data](https://github.com/vardius/peer-data) and socket signalling channel. 12 | 13 | To run this example simple clone the repository and perform the following from the root directory: 14 | 15 | ```sh 16 | ➜ examples git:(master) ✗ cd socket-channel 17 | ➜ socket-channel git:(master) ✗ yarn 18 | [1/4] 🔍 Resolving packages... 19 | success Already up-to-date. 20 | ✨ Done in 0.13s. 21 | ➜ socket-channel git:(master) ✗ yarn start 22 | $ node server.js 23 | Server started at port 3000 24 | ``` 25 | 26 | Then open [http://localhost:3000/](http://localhost:3000/). -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "rootDir": "src", 4 | "outDir": "build", 5 | "target": "es5", 6 | "module": "esnext", 7 | "moduleResolution": "node", 8 | "lib": [ 9 | "dom", 10 | "dom.iterable", 11 | "esnext", 12 | "scripthost" 13 | ], 14 | "sourceMap": true, 15 | "skipLibCheck": true, 16 | "noUnusedLocals": true, 17 | "allowJs": false, 18 | "esModuleInterop": true, 19 | "allowSyntheticDefaultImports": true, 20 | "strict": true, 21 | "forceConsistentCasingInFileNames": true, 22 | "resolveJsonModule": true, 23 | "noEmit": true, 24 | "noImplicitReturns": true, 25 | "noImplicitThis": true, 26 | "noImplicitAny": true, 27 | "strictNullChecks": true, 28 | "suppressImplicitAnyIndexErrors": true, 29 | "noUnusedParameters": true, 30 | "declaration": true, 31 | }, 32 | "include": [ 33 | "src/**/*" 34 | ], 35 | "exclude": [ 36 | "node_modules", 37 | "build", 38 | "dist", 39 | "example", 40 | "rollup.config.js" 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /website/docs/local.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: local 3 | title: Local connection 4 | sidebar_label: Local connection 5 | --- 6 | 7 | ## Example 8 | 9 | In the repository root directory you can find some simple examples. Click [here for local connection example](https://github.com/vardius/peer-data/tree/master/examples/local-connection). 10 | 11 | This simple project demonstrates how to setup WebRTC connection using [peer-data](https://github.com/vardius/peer-data) and custom signalling channel instead of builtin [SocketChannel](https://github.com/vardius/peer-data/blob/master/src/app/SocketChannel.ts). 12 | 13 | To run this example simple clone the repository and perform the following from the root directory: 14 | 15 | ```sh 16 | ➜ examples git:(master) ✗ cd local-connection 17 | ➜ local-connection git:(master) ✗ yarn 18 | [1/4] 🔍 Resolving packages... 19 | success Already up-to-date. 20 | ✨ Done in 0.13s. 21 | ➜ local-connection git:(master) ✗ yarn start 22 | $ node server.js 23 | Server started at port 3000 24 | ``` 25 | 26 | Then open [http://localhost:3000/](http://localhost:3000/). 27 | -------------------------------------------------------------------------------- /src/app/Signaling.ts: -------------------------------------------------------------------------------- 1 | export interface Identifiable { 2 | id: string; 3 | } 4 | 5 | type SignalingEventBase = { room: Identifiable; caller: Identifiable | null; callee: Identifiable | null }; 6 | 7 | export enum SignalingEventType { 8 | CONNECT = 'CONNECT', 9 | DISCONNECT = 'DISCONNECT', 10 | CANDIDATE = 'CANDIDATE', 11 | OFFER = 'OFFER', 12 | ANSWER = 'ANSWER', 13 | ERROR = 'ERROR', 14 | } 15 | 16 | export type SignalingEvent = 17 | | (SignalingEventBase & { type: SignalingEventType.CONNECT; payload: null }) 18 | | (SignalingEventBase & { type: SignalingEventType.DISCONNECT; payload: null }) 19 | | (SignalingEventBase & { type: SignalingEventType.CANDIDATE; payload: RTCIceCandidate }) 20 | | (SignalingEventBase & { type: SignalingEventType.OFFER; payload: RTCSessionDescriptionInit }) 21 | | (SignalingEventBase & { type: SignalingEventType.ANSWER; payload: RTCSessionDescriptionInit }) 22 | | (SignalingEventBase & { type: SignalingEventType.ERROR; payload: any | null }); 23 | 24 | export interface Signaling { 25 | onSend(message: SignalingEvent): void; 26 | } 27 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import resolve from "@rollup/plugin-node-resolve"; 2 | import commonjs from "@rollup/plugin-commonjs"; 3 | import sourcemaps from "rollup-plugin-sourcemaps"; 4 | import typescript from "rollup-plugin-typescript2"; 5 | 6 | const pkg = require("./package"); 7 | const external = Object.keys(pkg.peerDependencies); 8 | const env = process.env.NODE_ENV; 9 | const plugins = [ 10 | sourcemaps(), 11 | resolve({ 12 | browser: true, 13 | preferBuiltins: true, 14 | }), 15 | commonjs(), 16 | typescript({ 17 | objectHashIgnoreUnknownHack: true, 18 | clean: true, 19 | }), 20 | ]; 21 | 22 | const config = { 23 | input: "src/index.ts", 24 | external: external, 25 | plugins: plugins, 26 | treeshake: true, 27 | output: [ 28 | { 29 | name: pkg.name, 30 | exports: "named", 31 | file: pkg.module, 32 | format: "es", 33 | sourcemap: true, 34 | }, 35 | { 36 | name: pkg.name, 37 | exports: "named", 38 | file: pkg.main, 39 | format: "cjs", 40 | sourcemap: true, 41 | }, 42 | ], 43 | }; 44 | 45 | export default config; 46 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Rafał Lorenz 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/app/__tests__/Dispatcher.test.ts: -------------------------------------------------------------------------------- 1 | import { EventDispatcher } from '../EventDispatcher'; 2 | 3 | test('EventDispatcher is defined', (): void => { 4 | expect(EventDispatcher).toBeDefined(); 5 | }); 6 | 7 | test('EventDispatcher should dispatch global event', (): void => { 8 | let works = 0; 9 | const key = 'TEST'; 10 | 11 | const dispatcher = new EventDispatcher(); 12 | 13 | dispatcher.register(key, (): number => works++); 14 | dispatcher.dispatch(key); 15 | 16 | expect(works).toEqual(1); 17 | }); 18 | 19 | test('EventDispatcher should dispatch event', (): void => { 20 | let works = 0; 21 | const key = 'TEST'; 22 | const dispatcher = new EventDispatcher(); 23 | 24 | dispatcher.register(key, (): number => works++); 25 | dispatcher.dispatch(key); 26 | 27 | expect(works).toEqual(1); 28 | }); 29 | 30 | test('EventDispatcher should handle different events', (): void => { 31 | let works = 0; 32 | const key = 'TEST'; 33 | const key2 = 'OTHER'; 34 | const dispatcher = new EventDispatcher(); 35 | 36 | dispatcher.register(key, (): number => works++); 37 | dispatcher.register(key2, (): number => works--); 38 | dispatcher.dispatch(key); 39 | 40 | expect(works).toEqual(1); 41 | 42 | dispatcher.dispatch(key2); 43 | 44 | expect(works).toEqual(0); 45 | }); 46 | -------------------------------------------------------------------------------- /src/app/SocketChannel.ts: -------------------------------------------------------------------------------- 1 | import io from 'socket.io-client'; 2 | import { Signaling, SignalingEvent } from './Signaling'; 3 | import { EventDispatcher } from './EventDispatcher'; 4 | 5 | export class SocketChannel implements Signaling { 6 | private socket: SocketIOClient.Socket; 7 | private dispatcher: EventDispatcher; 8 | 9 | constructor(dispatcher: EventDispatcher , opts?: SocketIOClient.ConnectOpts) { 10 | this.dispatcher = dispatcher; 11 | this.socket = io(opts); 12 | 13 | this.dispatcher.register('send', this.onSend); 14 | 15 | this.subscribeEvents(); 16 | } 17 | 18 | onSend = (event: SignalingEvent): void => { 19 | this.socket.emit('message', event); 20 | }; 21 | 22 | private subscribeEvents = (): void => { 23 | this.socket.on('message', this.onMessage); 24 | this.socket.on('ipaddr', this.onIp); 25 | this.socket.on('log', this.onLog); 26 | }; 27 | 28 | private onIp = (ipaddr: string): void => { 29 | this.dispatcher.dispatch('log', 'Server IP address is: ' + ipaddr); 30 | }; 31 | 32 | private onLog = (...args: any[]): void => { 33 | this.dispatcher.dispatch('log', args); 34 | }; 35 | 36 | private onMessage = (event: SignalingEvent): void => { 37 | this.dispatcher.dispatch(event.type, event); 38 | }; 39 | } 40 | -------------------------------------------------------------------------------- /website/docs/data-channel.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: data-channel 3 | title: Data Channel 4 | sidebar_label: Data Channel 5 | --- 6 | 7 | ## [What is a data channel?](https://developer.mozilla.org/en-US/docs/Games/Techniques/WebRTC_data_channels#What_is_a_data_channel) 8 | 9 | A WebRTC data channel lets you send text or binary data over an active connection to a peer. In the context of a game, this lets players send data to each other, whether text chat or game status information. Data channels come in two flavors. 10 | 11 | ## Example 12 | 13 | ```typescript 14 | import PeerData, { EventDispatcher, SocketChannel } from 'peer-data'; 15 | 16 | const constraints = {ordered: true}; 17 | const servers = { 18 | iceServers: [ 19 | {urls: "stun:stun.1.google.com:19302"} 20 | ] 21 | }; 22 | 23 | const dispatcher = new EventDispatcher(); 24 | const peerData = new PeerData(dispatcher, servers, constraints); 25 | const signaling = new SocketChannel(dispatcher, 'http://localhost:8080'); 26 | 27 | const room = peerData.connect('test-room'); 28 | 29 | //payload object can be everything 30 | const payload = {msg: "Hi there!", date: now()}; 31 | //send to everybody in room 32 | room.send(payload); 33 | 34 | room.on("participant", participant => { 35 | //this peer sent a message 36 | participant.on("message", payload => console.log("message", payload)); 37 | 38 | //send only to participant 39 | participant.send('Hi mate! this is private message.'); 40 | }); 41 | ``` 42 | -------------------------------------------------------------------------------- /examples/socket-channel/remote.js: -------------------------------------------------------------------------------- 1 | const dispatcher = new window.EventDispatcher(); 2 | const signaling = new window.SocketChannel(dispatcher, 'http://localhost:3000'); 3 | 4 | // Set up servers 5 | const servers = { 6 | iceServers: [{ urls: "stun:stun.1.google.com:19302" }], 7 | }; 8 | 9 | const peerData = new window.PeerData(dispatcher, servers); 10 | let room = null; 11 | 12 | async function connect(e) { 13 | if (room) { 14 | return; 15 | } 16 | 17 | // remote stream will receive our local stream and share it back for purpose of this example 18 | room = peerData.connect("test-room"); 19 | room 20 | // you can catch errors here to know if the peer connection init failed 21 | .on("error", (event) => console.error("remote:error", event)) 22 | .on("participant", (participant) => { 23 | // handle this participant error 24 | participant.on("error", (event) => console.error("participant:error", event)); 25 | 26 | // this peer disconnected from room 27 | participant.on("disconnected", () => { 28 | console.log("remote:disconnected", event); 29 | 30 | // local peer has disconnected so we do the same, leave the room 31 | room.disconnect(); 32 | room = null; 33 | }); 34 | 35 | // this peer shared a stream 36 | participant.on("track", (event) => { 37 | console.log("remote:track", event); 38 | participant.addStream(event.streams[0]); 39 | }); 40 | }); 41 | } 42 | 43 | document.querySelector("#connect").addEventListener("click", (e) => connect(e)); 44 | -------------------------------------------------------------------------------- /website/src/pages/en/users.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | const React = require("react"); 9 | 10 | const CompLibrary = require("../../core/CompLibrary.js"); 11 | 12 | const Container = CompLibrary.Container; 13 | 14 | class Users extends React.Component { 15 | render() { 16 | const { config: siteConfig } = this.props; 17 | if ((siteConfig.users || []).length === 0) { 18 | return null; 19 | } 20 | 21 | const editUrl = `${siteConfig.repoUrl}/edit/master/website/siteConfig.js`; 22 | const showcase = siteConfig.users.map(user => ( 23 | 24 | {user.caption} 25 | 26 | )); 27 | 28 | return ( 29 |
30 | 31 |
32 |
33 |

Who is Using This?

34 |

This project is used by many folks

35 |
36 |
{showcase}
37 |

Are you using this project?

38 | 39 | Add your company 40 | 41 |
42 |
43 |
44 | ); 45 | } 46 | } 47 | 48 | module.exports = Users; 49 | -------------------------------------------------------------------------------- /website/docs/installation.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: installation 3 | title: Getting Started 4 | sidebar_label: Installation 5 | --- 6 | 7 | *_PeerData_* is a library for bidirectional peer-to-peer transfers of arbitrary data using [RTCDataChannel](https://developer.mozilla.org/pl/docs/Web/API/RTCDataChannel). Simple *WebRTC* wrapper providing data channel abstraction. 8 | 9 | [WebRTC](https://webrtc.org/) needs a messaging service to set up and maintain a *WebRTC* call. 10 | 11 | The sender and receiver *RTCPeerConnections* run in web pages on different devices, and we need a way for them to communicate metadata. 12 | For this, we use a signaling server: a server that can pass messages between *WebRTC* clients (peers). 13 | 14 | [PeerDataServer](https://github.com/vardius/peer-data-server) - An **ready to use** example of signaling server on *Node* using [socket.io](http://socket.io/). 15 | 16 | ## Installation 17 | 18 | 19 | 20 | ```yarn 21 | npm install peer-data 22 | ``` 23 | 24 | ```bash 25 | yarn add peer-data 26 | ``` 27 | 28 | 29 | [WebRTC Chat](https://github.com/vardius/webrtc-chat) server-less example application. 30 | 31 | [Shared versus Many `RCTPeerConnection`](https://bloggeek.me/webrtc-rtcpeerconnection-one-per-stream/) 32 | 33 | *_PeerData_* runs multiple `RCTPeerConnection` - one per user. Why? Main reason because it is easier to manage participants. With multiple `RTCPeerConnection` we’ve got a lot more flexibility, since the sessions are independent – each encapsulated in its own `RTCPeerConnection`. 34 | -------------------------------------------------------------------------------- /examples/local-connection/remote.js: -------------------------------------------------------------------------------- 1 | window.remoteDispatcher.register("send", (event) => { 2 | console.log("remoteDispatcher:send", event); 3 | window.localDispatcher.dispatch(event.type, event); 4 | }); 5 | 6 | // Set up servers 7 | const servers = { 8 | iceServers: [{ urls: "stun:stun.1.google.com:19302" }], 9 | }; 10 | 11 | const peerData = new window.PeerData(window.remoteDispatcher, servers); 12 | let room = null; 13 | 14 | async function connect(e) { 15 | if (room) { 16 | return; 17 | } 18 | 19 | // remote stream will receive our local stream and share it back for purpose of this example 20 | room = peerData.connect("test-room"); 21 | room 22 | // you can catch errors here to know if the peer connection init failed 23 | .on("error", (event) => console.error("remote:error", event)) 24 | .on("participant", (participant) => { 25 | // handle this participant error 26 | participant.on("error", (event) => console.error("participant:error", event)); 27 | 28 | // this peer disconnected from room 29 | participant.on("disconnected", () => { 30 | console.log("remote:disconnected", event); 31 | 32 | // local peer has disconnected so we do the same, leave the room 33 | room.disconnect(); 34 | room = null; 35 | }); 36 | 37 | // this peer shared a stream 38 | participant.on("track", (event) => { 39 | console.log("remote:track", event); 40 | participant.addStream(event.streams[0]); 41 | }); 42 | }); 43 | } 44 | 45 | document.querySelector("#connect").addEventListener("click", (e) => connect(e)); -------------------------------------------------------------------------------- /website/docs/client.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: client 3 | title: Basic Example 4 | sidebar_label: Basic Example 5 | --- 6 | 7 | ## [WebRTC (Web Real-Time Communications)](https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API) 8 | 9 | WebRTC is designed to work peer-to-peer, so users can connect by the most direct route possible. However, WebRTC is built to cope with real-world networking: client applications need to traverse NAT gateways and firewalls, and peer to peer networking needs fallbacks in case direct connection fails. As part of this process, the WebRTC APIs use STUN servers to get the IP address of your computer, and TURN servers to function as relay servers in case peer-to-peer communication fails. (WebRTC in the real world explains in more detail.) 10 | 11 | ## Example 12 | 13 | ```typescript 14 | import PeerData, { EventDispatcher, SocketChannel } from 'peer-data'; 15 | 16 | const servers = { 17 | iceServers: [ 18 | {urls: "stun:stun.1.google.com:19302"} 19 | ] 20 | }; 21 | 22 | const dispatcher = new EventDispatcher(); 23 | const peerData = new PeerData(dispatcher, servers); 24 | const signaling = new SocketChannel(dispatcher, 'http://localhost:8080'); 25 | 26 | const room = peerData.connect('test-room'); 27 | 28 | // returns participant object 29 | room.on("participant", participant => { 30 | //this peer disconnected from room 31 | participant.on("disconnected", () => console.log("disconnected")); 32 | 33 | //close connection, will dispatch disconnected event 34 | participant.close(); 35 | }); 36 | 37 | //exit room, will disconnect from all peers 38 | room.disconnect(); 39 | ``` 40 | -------------------------------------------------------------------------------- /examples/data-channel/remote.js: -------------------------------------------------------------------------------- 1 | window.remoteDispatcher.register("send", (event) => { 2 | console.log("remoteDispatcher:send", event); 3 | window.localDispatcher.dispatch(event.type, event); 4 | }); 5 | 6 | const constraints = {ordered: true}; 7 | const servers = { 8 | iceServers: [{ urls: "stun:stun.1.google.com:19302" }], 9 | }; 10 | 11 | const peerData = new window.PeerData(window.remoteDispatcher, servers, constraints); 12 | let room = null; 13 | 14 | async function connect(e) { 15 | if (room) { 16 | return; 17 | } 18 | 19 | // remote stream will receive our local stream and share it back for purpose of this example 20 | room = peerData.connect("test-room"); 21 | room 22 | // you can catch errors here to know if the peer connection init failed 23 | .on("error", (event) => console.error("remote:error", event)) 24 | .on("participant", (participant) => { 25 | // handle this participant error 26 | participant.on("error", (event) => console.error("participant:error", event)); 27 | 28 | participant.on("message", payload => { 29 | if (document.getElementById("remoteMessage").value !== "") { 30 | document.getElementById("remoteMessage").value += "\n" 31 | } 32 | document.getElementById("remoteMessage").value += payload 33 | }); 34 | 35 | // this peer disconnected from room 36 | participant.on("disconnected", () => { 37 | console.log("remote:disconnected", event); 38 | 39 | // local peer has disconnected so we do the same, leave the room 40 | room.disconnect(); 41 | room = null; 42 | }); 43 | }); 44 | } 45 | 46 | document.querySelector("#connect").addEventListener("click", (e) => connect(e)); -------------------------------------------------------------------------------- /examples/data-channel/local.js: -------------------------------------------------------------------------------- 1 | // Custom signaling system (we do not built in socket.io for local example) 2 | window.localDispatcher.register("send", (event) => { 3 | console.log("localDispatcher:send", event); 4 | window.remoteDispatcher.dispatch(event.type, event); 5 | }); 6 | 7 | const constraints = {ordered: true}; 8 | const servers = { 9 | iceServers: [{ urls: "stun:stun.1.google.com:19302" }], 10 | }; 11 | 12 | const peerData = new window.PeerData(window.localDispatcher, servers, constraints); 13 | let room = null; 14 | let remoteParticipant = null; 15 | 16 | async function connect(e) { 17 | if (room) { 18 | return; 19 | } 20 | 21 | // share our stream 22 | room = peerData.connect("test-room"); 23 | room 24 | // you can catch errors here to know if the peer connection init failed 25 | .on("error", (event) => console.error("local:error", event)) 26 | .on("participant", (participant) => { 27 | remoteParticipant = participant; 28 | 29 | // handle this participant error 30 | participant.on("error", (event) => console.error("participant:error", event)); 31 | }); 32 | } 33 | 34 | async function disconnect(e) { 35 | if (room) { 36 | room.disconnect(); 37 | console.log('btn:disconnect'); 38 | room = null; 39 | remoteParticipant = null; 40 | } 41 | } 42 | 43 | async function send(e) { 44 | if (remoteParticipant) { 45 | remoteParticipant.send(document.getElementById("localMessage").value); 46 | document.getElementById("localMessage").value = ''; 47 | } 48 | } 49 | 50 | document.querySelector("#send").addEventListener("click", (e) => send(e)); 51 | document.querySelector("#connect").addEventListener("click", (e) => connect(e)); 52 | document.querySelector("#disconnect").addEventListener("click", (e) => disconnect(e)); 53 | -------------------------------------------------------------------------------- /examples/socket-channel/local.js: -------------------------------------------------------------------------------- 1 | const dispatcher = new window.EventDispatcher(); 2 | const signalling = new window.SocketChannel(dispatcher, 'http://localhost:3000'); 3 | 4 | // Set up servers 5 | const servers = { 6 | iceServers: [{ urls: "stun:stun.1.google.com:19302" }], 7 | }; 8 | 9 | const peerData = new window.PeerData(dispatcher, servers); 10 | let room = null; 11 | 12 | // get video/voice stream 13 | navigator.getUserMedia({ video: true, audio: true }, gotMedia, () => {}); 14 | 15 | function gotMedia(stream) { 16 | window.stream = stream; // make variable available to browser console 17 | 18 | const video = document.querySelector("#localVideo"); 19 | video.srcObject = stream; 20 | } 21 | 22 | async function connect(e) { 23 | if (room) { 24 | return; 25 | } 26 | 27 | // share our stream 28 | room = peerData.connect("test-room", window.stream); 29 | room 30 | // you can catch errors here to know if the peer connection init failed 31 | .on("error", (event) => console.error("local:error", event)) 32 | .on("participant", (participant) => { 33 | // handle this participant error 34 | participant.on("error", (event) => console.error("participant:error", event)); 35 | 36 | //this peer shared a stream 37 | participant.on("track", (event) => { 38 | console.log("local:track", event); 39 | 40 | const video = document.querySelector("#remoteVideo"); 41 | if (video.srcObject !== event.streams[0]) { 42 | video.srcObject = event.streams[0]; 43 | } 44 | }); 45 | }); 46 | } 47 | 48 | async function disconnect(e) { 49 | if (room) { 50 | room.disconnect(); 51 | console.log('btn:disconnect'); 52 | room = null; 53 | } 54 | } 55 | 56 | document.querySelector("#connect").addEventListener("click", (e) => connect(e)); 57 | document.querySelector("#disconnect").addEventListener("click", (e) => disconnect(e)); 58 | -------------------------------------------------------------------------------- /website/docs/media-stream.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: media-stream 3 | title: Media Stream 4 | sidebar_label: Media Stream 5 | --- 6 | 7 | ## [Media Capture and Streams Concepts and Usage](https://developer.mozilla.org/en-US/docs/Web/API/Media_Streams_API#Media_Capture_and_Streams_Concepts_and_Usage) 8 | 9 | The Media Capture and Streams API, often called the Media Streams API or simply MediaStream API, is an API related to WebRTC which provides support for streaming audio and video data. 10 | It provides the interfaces and methods for working with the streams and their constituent tracks, the constraints associated with data formats, the success and error callbacks when using the data asynchronously, and the events that are fired during the process. 11 | 12 | ## Example 13 | 14 | ```javascript 15 | // get video/voice stream 16 | navigator.getUserMedia({ video: true, audio: true }, gotMedia, () => {}) 17 | 18 | function gotMedia (stream) { 19 | // passing stream is optional, if passed will be shared between all peers in current room 20 | const room = peerData.connect('test-room', stream); 21 | 22 | room.on("participant", participant => { 23 | //this peer shared a stream 24 | participant.on("track", event => { 25 | const stream = event.streams[0]; 26 | console.log("track", event, stream); 27 | }); 28 | }); 29 | } 30 | ``` 31 | 32 | ## Add stream to existing connection 33 | ```javascript 34 | import PeerData from 'peer-data'; 35 | 36 | const servers = { 37 | iceServers: [ 38 | {urls: "stun:stun.1.google.com:19302"} 39 | ] 40 | }; 41 | 42 | const peerData = new PeerData(servers); 43 | const room = peerData.connect('test-room'); 44 | 45 | room.on("participant", participant => { 46 | navigator.mediaDevices 47 | .getUserMedia({video: true}) 48 | .then(stream => { 49 | participant.addStream(stream); 50 | participant.renegotiate(); 51 | }); 52 | }); 53 | ``` -------------------------------------------------------------------------------- /examples/local-connection/local.js: -------------------------------------------------------------------------------- 1 | // Custom signaling system (we do not built in socket.io for local example) 2 | window.localDispatcher.register("send", (event) => { 3 | console.log("localDispatcher:send", event); 4 | window.remoteDispatcher.dispatch(event.type, event); 5 | }); 6 | 7 | // Set up servers 8 | const servers = { 9 | iceServers: [{ urls: "stun:stun.1.google.com:19302" }], 10 | }; 11 | 12 | const peerData = new window.PeerData(window.localDispatcher, servers); 13 | let room = null; 14 | 15 | // get video/voice stream 16 | navigator.getUserMedia({ video: true, audio: true }, gotMedia, () => {}); 17 | 18 | function gotMedia(stream) { 19 | window.stream = stream; // make variable available to browser console 20 | 21 | const video = document.querySelector("#localVideo"); 22 | video.srcObject = stream; 23 | } 24 | 25 | async function connect(e) { 26 | if (room) { 27 | return; 28 | } 29 | 30 | // share our stream 31 | room = peerData.connect("test-room", window.stream); 32 | room 33 | // you can catch errors here to know if the peer connection init failed 34 | .on("error", (event) => console.error("local:error", event)) 35 | .on("participant", (participant) => { 36 | // handle this participant error 37 | participant.on("error", (event) => console.error("participant:error", event)); 38 | 39 | //this peer shared a stream 40 | participant.on("track", (event) => { 41 | console.log("local:track", event); 42 | 43 | const video = document.querySelector("#remoteVideo"); 44 | if (video.srcObject !== event.streams[0]) { 45 | video.srcObject = event.streams[0]; 46 | } 47 | }); 48 | }); 49 | } 50 | 51 | async function disconnect(e) { 52 | if (room) { 53 | room.disconnect(); 54 | console.log('btn:disconnect'); 55 | room = null; 56 | } 57 | } 58 | 59 | document.querySelector("#connect").addEventListener("click", (e) => connect(e)); 60 | document.querySelector("#disconnect").addEventListener("click", (e) => disconnect(e)); 61 | -------------------------------------------------------------------------------- /src/app/App.ts: -------------------------------------------------------------------------------- 1 | import { EventDispatcher } from './EventDispatcher'; 2 | import { SignalingEvent, SignalingEventType } from './Signaling'; 3 | import { Configuration } from './Configuration'; 4 | import { Room } from './Room'; 5 | 6 | export class App { 7 | private dispatcher: EventDispatcher; 8 | private configuration: Configuration = new Configuration(); 9 | private rooms: Map = new Map(); 10 | 11 | constructor(dispatcher: EventDispatcher, servers: RTCConfiguration = {}, dataConstraints?: RTCDataChannelInit) { 12 | this.dispatcher = dispatcher; 13 | 14 | this.configuration.setServers(servers); 15 | 16 | if (dataConstraints) { this.configuration.setDataConstraints(dataConstraints); } 17 | 18 | this.dispatcher.register(SignalingEventType.CONNECT, this.onEvent); 19 | this.dispatcher.register(SignalingEventType.OFFER, this.onEvent); 20 | this.dispatcher.register(SignalingEventType.DISCONNECT, this.onEvent); 21 | this.dispatcher.register(SignalingEventType.ANSWER, this.onEvent); 22 | this.dispatcher.register(SignalingEventType.CANDIDATE, this.onEvent); 23 | this.dispatcher.register('send', this.onDisconnected); 24 | } 25 | 26 | getEventDispatcher = (): EventDispatcher => this.dispatcher; 27 | 28 | getConfiguration = (): Configuration => this.configuration; 29 | 30 | connect = (id: string, stream?: MediaStream): Room => { 31 | if (this.rooms.has(id)) { 32 | return this.rooms.get(id) as Room; 33 | } 34 | 35 | const room = new Room(id, this.configuration, this.dispatcher, stream); 36 | this.rooms.set(id, room); 37 | 38 | return room; 39 | }; 40 | 41 | private onEvent = (event: SignalingEvent): App => { 42 | if (this.rooms.has(event.room.id)) { 43 | const room = (this.rooms.get(event.room.id) as Room); 44 | 45 | room.onSignalingEvent(event); 46 | } 47 | 48 | return this; 49 | }; 50 | 51 | private onDisconnected = (event: SignalingEvent): void => { 52 | if (event.type === SignalingEventType.DISCONNECT) { 53 | this.rooms.delete(event.room.id); 54 | } 55 | }; 56 | } 57 | -------------------------------------------------------------------------------- /website/src/pages/en/help.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | const React = require("react"); 9 | 10 | const CompLibrary = require("../../core/CompLibrary.js"); 11 | 12 | const Container = CompLibrary.Container; 13 | const GridBlock = CompLibrary.GridBlock; 14 | 15 | function Help(props) { 16 | const { config: siteConfig, language = "" } = props; 17 | const { baseUrl, docsUrl } = siteConfig; 18 | const docsPart = `${docsUrl ? `${docsUrl}/` : ""}`; 19 | const langPart = `${language ? `${language}/` : ""}`; 20 | const docUrl = doc => `${baseUrl}${docsPart}${langPart}${doc}`; 21 | 22 | const supportLinks = [ 23 | { 24 | content: `Learn more using the [documentation on this site.](${docUrl( 25 | "installation.html" 26 | )})`, 27 | title: "Browse Docs" 28 | }, 29 | { 30 | content: 31 | "[Ask questions](https://github.com/vardius/peer-data/issues) about the documentation and project", 32 | title: "Join the community" 33 | }, 34 | { 35 | content: 36 | "Find out [what's new](https://github.com/vardius/peer-data/watchers) with this project", 37 | title: "Stay up to date" 38 | }, 39 | { 40 | content: 41 | "Consider support this project by [sponsoring](https://github.com/sponsors/vardius)", 42 | title: "Support" 43 | }, 44 | { 45 | content: 46 | "Contribute by [forking](https://github.com/vardius/peer-data/network/members) and improving this project", 47 | title: "Contribute" 48 | } 49 | ]; 50 | 51 | return ( 52 |
53 | 54 |
55 |
56 |

Need help?

57 |
58 |

This project is maintained by a dedicated group of people.

59 | 60 |
61 |
62 |
63 | ); 64 | } 65 | 66 | module.exports = Help; 67 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | We are open to, and grateful for, any contributions made by the community. By contributing to **peer-data**, you agree to abide by the [code of conduct](https://github.com/vardius/peer-data/blob/master/CODE_OF_CONDUCT.md). 4 | 5 | ## Reporting Issues and Asking Questions 6 | 7 | Before opening an issue, please search the [issue tracker](https://github.com/vardius/peer-data/issues) to make sure your issue hasn't already been reported. 8 | 9 | ### Bugs and Improvements 10 | 11 | We use the issue tracker to keep track of bugs and improvements to **peer-data** itself, its examples, and the documentation. We encourage you to open issues to discuss improvements, architecture, theory, internal implementation, etc. If a topic has been discussed before, we will ask you to join the previous discussion. 12 | 13 | Any pull requests that involve breaking changes should be made against the `next` branch. 14 | 15 | ### Getting Help 16 | 17 | For support or usage questions like “how do I do X with **peer-data**” and “my code doesn't work”, we encourage you to post an issue. 18 | 19 | Please be considerate when doing this as this is not the primary purpose of the issue tracker. 20 | 21 | ## Development 22 | 23 | Visit the [issue tracker](https://github.com/vardius/peer-data/issues) to find a list of open issues that need attention. 24 | 25 | Fork, then clone the repo: 26 | 27 | ``` 28 | git clone https://github.com/your-username/peer-data.git 29 | ``` 30 | 31 | ### Docs 32 | 33 | Improvements to the documentation are always welcome. In the docs we abide by typographic rules, so instead of ' you should use '. Same goes for “ ” and dashes (—) where appropriate. These rules only apply to the text, not to code blocks. 34 | 35 | ### Sending a Pull Request 36 | 37 | For non-trivial changes, please open an issue with a proposal for a new feature or refactoring before starting on the work. We don't want you to waste your efforts on a pull request that we won't want to accept. 38 | 39 | On the other hand, sometimes the best way to start a conversation *is* to send a pull request. Use your best judgement! 40 | 41 | In general, the contribution workflow looks like this: 42 | 43 | * Open a new issue in the [Issue tracker](https://github.com/vardius/peer-data/issues). 44 | * Fork the repo. 45 | * Create a new feature branch based off the `master` branch. 46 | * Make sure all tests pass and there are no linting errors. 47 | * Submit a pull request, referencing any issues it addresses. 48 | 49 | Please try to keep your pull request focused in scope and avoid including unrelated commits. 50 | 51 | After you have submitted your pull request, we'll try to get back to you as soon as possible. We may suggest some changes or improvements. 52 | 53 | Thank you for contributing! 54 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "peer-data", 3 | "version": "3.2.5", 4 | "description": "PeerData - library for files, media streaming/sharing using WebRTC", 5 | "scripts": { 6 | "build": "rollup -c", 7 | "clean": "rimraf dist coverage", 8 | "typecheck": "tsc --noEmit", 9 | "lint": "eslint -c .eslintrc.js --ext .ts src", 10 | "test": "jest --no-cache", 11 | "test:cov": "yarn test -- --coverage", 12 | "test:watch": "yarn test -- --watchAll", 13 | "prepare": "yarn build", 14 | "prebuild": "yarn clean", 15 | "postbuild": "rimraf dist/**/__tests__", 16 | "posttest": "yarn typecheck && yarn lint", 17 | "preversion": "yarn test", 18 | "postversion": "git push && git push --tags", 19 | "check": "npm-check -u" 20 | }, 21 | "main": "dist/index.js", 22 | "module": "dist/index.es.js", 23 | "jsnext:main": "dist/index.es.js", 24 | "types": "dist/index.d.ts", 25 | "repository": { 26 | "type": "git", 27 | "url": "git+https://github.com/vardius/peer-data.git" 28 | }, 29 | "files": [ 30 | "dist" 31 | ], 32 | "keywords": [ 33 | "PeerData", 34 | "WebRTC", 35 | "cdn", 36 | "web", 37 | "rtc", 38 | "video", 39 | "player", 40 | "html5", 41 | "peer", 42 | "socket", 43 | "real", 44 | "time", 45 | "communication" 46 | ], 47 | "author": { 48 | "name": "Rafał Lorenz", 49 | "email": "vardius@gmail.com" 50 | }, 51 | "license": "MIT", 52 | "bugs": { 53 | "url": "https://github.com/vardius/peer-data/issues" 54 | }, 55 | "homepage": "https://github.com/vardius/peer-data#readme", 56 | "jest": { 57 | "transform": { 58 | ".(ts?)": "ts-jest" 59 | }, 60 | "testMatch": [ 61 | "**/?(*.)(spec|test).{t,j}s" 62 | ], 63 | "testPathIgnorePatterns": [ 64 | "/(node_modules|lib|es|dist)" 65 | ], 66 | "collectCoverageFrom": [ 67 | "src/**/*.{t,j}s", 68 | "!src/**/*.d.ts" 69 | ], 70 | "moduleFileExtensions": [ 71 | "js", 72 | "json", 73 | "ts" 74 | ] 75 | }, 76 | "peerDependencies": { 77 | "webrtc-adapter": "^7.2.3" 78 | }, 79 | "dependencies": { 80 | "@types/uuid": "^8.0.0", 81 | "socket.io-client": "^2.3.0", 82 | "uuid": "^8.1.0" 83 | }, 84 | "devDependencies": { 85 | "@rollup/plugin-commonjs": "^11.0.2", 86 | "@rollup/plugin-node-resolve": "^7.1.1", 87 | "@types/jest": "^25.1.2", 88 | "@types/node": "^13.7.0", 89 | "@types/socket.io-client": "^1.4.29", 90 | "@types/webrtc": "0.0.25", 91 | "@typescript-eslint/eslint-plugin": "^2.19.0", 92 | "@typescript-eslint/parser": "^2.19.0", 93 | "codecov": "^3.6.5", 94 | "cross-env": "^7.0.0", 95 | "dts-bundle": "^0.7.3", 96 | "eslint": "^6.8.0", 97 | "jest": "^25.1.0", 98 | "jest-cli": "^25.1.0", 99 | "jest-environment-node-debug": "^2.0.0", 100 | "npm-check": "^5.7.1", 101 | "rimraf": "^3.0.1", 102 | "rollup": "^1.31.0", 103 | "rollup-plugin-sourcemaps": "^0.5.0", 104 | "rollup-plugin-typescript2": "^0.25.3", 105 | "ts-jest": "^25.2.0", 106 | "tslib": "^1.10.0", 107 | "typescript": "^3.7.5" 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PeerData 2 | [![Build Status](https://travis-ci.org/vardius/peer-data.svg?branch=master)](https://travis-ci.org/vardius/peer-data) 3 | [![npm version](https://img.shields.io/npm/v/peer-data.svg)](https://www.npmjs.com/package/peer-data) 4 | [![npm downloads](https://img.shields.io/npm/dm/peer-data.svg)](https://www.npmjs.com/package/peer-data) 5 | [![license](https://img.shields.io/github/license/vardius/peer-data.svg)](LICENSE) 6 | 7 | 8 | logo 9 | 10 | PeerData is a library for bidirectional peer-to-peer transfers of arbitrary data using [RTCDataChannel](https://developer.mozilla.org/pl/docs/Web/API/RTCDataChannel). Simple *WebRTC* wrapper providing data channel abstraction. 11 | 12 | [WebRTC](https://webrtc.org/) needs a messaging service to set up and maintain a *WebRTC* call. 13 | 14 | The sender and receiver *RTCPeerConnections* run in web pages on different devices, and we need a way for them to communicate metadata. 15 | For this, we use a signaling server: a server that can pass messages between *WebRTC* clients (peers). 16 | 17 | [PeerDataServer](https://github.com/vardius/peer-data-server) - An **ready to use** example of signaling server on *Node* using [socket.io](http://socket.io/). 18 | 19 | 📖 ABOUT 20 | ================================================== 21 | Contributors: 22 | 23 | * [Rafał Lorenz](https://rafallorenz.com) 24 | 25 | Want to contribute ? Feel free to send pull requests! 26 | 27 | Have problems, bugs, feature ideas? 28 | We are using the github [issue tracker](https://github.com/vardius/peer-data/issues) to manage them. 29 | 30 | ## 📚 Documentation 31 | 32 | For **documentation** (_including examples_), **visit [rafallorenz.com/peer-data](https://rafallorenz.com/peer-data)** 33 | 34 | 🚏 HOW TO USE 35 | ================================================== 36 | 37 | 1. [Chat Example](https://github.com/vardius/webrtc-chat) 38 | 2. [React Chat Example](https://github.com/vardius/react-webrtc-chat) 39 | 3. [React Hook](https://github.com/vardius/react-peer-data) 40 | 41 | ## Installation 42 | ```bash 43 | $ npm install peer-data 44 | ``` 45 | 46 | ## Basic example 47 | ```typescript 48 | import PeerData, { EventDispatcher, SocketChannel } from 'peer-data'; 49 | 50 | const constraints = {ordered: true}; 51 | const servers = { 52 | iceServers: [ 53 | {urls: "stun:stun.1.google.com:19302"} 54 | ] 55 | }; 56 | 57 | const dispatcher = new EventDispatcher(); 58 | const peerData = new PeerData(dispatcher, servers, constraints); 59 | const signaling = new SocketChannel(dispatcher, 'http://localhost:8080'); 60 | 61 | const room = peerData.connect('test-room'); 62 | 63 | room.on("participant", participant => { 64 | participant.on("message", payload => console.log("message", payload)); 65 | 66 | participant.send('Hi mate! this is private message.'); 67 | }) 68 | ``` 69 | 70 | For how to **disconnect**, **close connection** and handle errors please check [documentation](https://rafallorenz.com/peer-data/docs/client). 71 | 72 | 📜 [License](LICENSE.md) 73 | ------- 74 | 75 | This package is released under the MIT license. See the complete license in the package 76 | -------------------------------------------------------------------------------- /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at vardius@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /website/src/core/Footer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | const React = require("react"); 9 | 10 | class Footer extends React.Component { 11 | docUrl(doc, language) { 12 | const baseUrl = this.props.config.baseUrl; 13 | const docsUrl = this.props.config.docsUrl; 14 | const docsPart = `${docsUrl ? `${docsUrl}/` : ""}`; 15 | const langPart = `${language ? `${language}/` : ""}`; 16 | return `${baseUrl}${docsPart}${langPart}${doc}`; 17 | } 18 | 19 | pageUrl(doc, language) { 20 | const baseUrl = this.props.config.baseUrl; 21 | return baseUrl + (language ? `${language}/` : "") + doc; 22 | } 23 | 24 | render() { 25 | return ( 26 | 95 | ); 96 | } 97 | } 98 | 99 | module.exports = Footer; 100 | -------------------------------------------------------------------------------- /examples/local-connection/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | PeerData - local connection example 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 |
26 |
27 |

Example

28 |

local connection with custom signaling channel

29 |

30 | 31 | 32 |

33 |
34 |
35 | 36 |
37 |
38 |
39 |
40 |
41 | 42 |
43 |

local connection

44 |
45 |
46 |
47 |
48 |
49 | 50 |
51 |

remote connection

52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /examples/socket-channel/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | PeerData - socket signalling channel example 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 |
26 |
27 |

Example

28 |

local connection with socket signalling channel

29 |

30 | 31 | 32 |

33 |
34 |
35 | 36 |
37 |
38 |
39 |
40 |
41 | 42 |
43 |

local connection

44 |
45 |
46 |
47 |
48 |
49 | 50 |
51 |

remote connection

52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /examples/data-channel/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | PeerData - data channel example 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 |
26 |
27 |

Example

28 |

local connection with data channel

29 |

30 | 31 | 32 |

33 |
34 |
35 | 36 |
37 |
38 |
39 |
40 |
41 | 42 |
43 | 44 |

local connection

45 |
46 |
47 |
48 |
49 |
50 | 51 |
52 |

remote connection

53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /website/src/siteConfig.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | // See https://docusaurus.io/docs/site-config for all the possible 9 | // site configuration options. 10 | 11 | // List of projects/orgs using your project for the users page. 12 | const users = [ 13 | // { 14 | // caption: "go-api-boilerplate", 15 | // // You will need to prepend the image path with your baseUrl 16 | // // if it is not '/', like: '/test-site/img/image.jpg'. 17 | // image: "/img/undraw_open_source.svg", 18 | // infoLink: "https://github.com/vardius/go-api-boilerplate", 19 | // pinned: true 20 | // } 21 | ]; 22 | 23 | const siteConfig = { 24 | title: "peer-data", // Title for your website. 25 | tagline: 26 | "Library for files, media streaming/sharing using WebRTC", 27 | url: "https://rafallorenz.com", // Your website URL 28 | baseUrl: "/peer-data/", // Base URL for your project */ 29 | // For github.io type URLs, you would set the url and baseUrl like: 30 | // url: 'https://facebook.github.io', 31 | // baseUrl: '/test-site/', 32 | 33 | // Used for publishing and more 34 | projectName: "peer-data", 35 | organizationName: "vardius", 36 | // For top-level user or org sites, the organization is still the same. 37 | // e.g., for the https://JoelMarcey.github.io site, it would be set like... 38 | // organizationName: 'JoelMarcey' 39 | 40 | // For no header links in the top nav bar -> headerLinks: [], 41 | headerLinks: [ 42 | { doc: "installation", label: "Docs" }, 43 | { page: "help", label: "Help" }, 44 | // { page: "users", label: "Users" }, 45 | { href: "https://github.com/vardius/peer-data", label: "GitHub" } 46 | // { blog: true, label: 'Blog'}, 47 | // { languages: true }, 48 | // { search: true } 49 | ], 50 | 51 | docsSideNavCollapsible: true, 52 | 53 | // If you have users set above, you add it here: 54 | users, 55 | 56 | /* path to images for header/footer */ 57 | headerIcon: "favicon/ms-icon-310x310.png", 58 | footerIcon: "favicon/ms-icon-310x310.png", 59 | favicon: "favicon/favicon.ico", 60 | 61 | /* Colors for website */ 62 | colors: { 63 | primaryColor: "#4c383f", 64 | secondaryColor: "#cfb29d" 65 | }, 66 | 67 | /* Custom fonts for website */ 68 | /* 69 | fonts: { 70 | myFont: [ 71 | "Times New Roman", 72 | "Serif" 73 | ], 74 | myOtherFont: [ 75 | "-apple-system", 76 | "system-ui" 77 | ] 78 | }, 79 | */ 80 | 81 | // This copyright info is used in /core/Footer.js and blog RSS/Atom feeds. 82 | copyright: `Copyright © ${new Date().getFullYear()} Rafał Lorenz`, 83 | 84 | highlight: { 85 | // Highlight.js theme to use for syntax highlighting in code blocks. 86 | theme: "darcula" 87 | }, 88 | 89 | // Add custom scripts here that would be placed in